package com.yanqu.road.server.manager.activity.suitang.activity;

import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.suitang.config.SuiTangCampBoxConfig;
import com.yanqu.road.entity.activity.suitang.config.SuiTangCityConfig;
import com.yanqu.road.entity.activity.suitang.config.SuiTangCityTypeConfig;
import com.yanqu.road.entity.activity.suitang.config.SuiTangGuessConfig;
import com.yanqu.road.entity.activity.suitang.data.*;
import com.yanqu.road.entity.activity.suitang.entity.barracks.CrossSuiTangBarracks;
import com.yanqu.road.entity.activity.suitang.entity.battle.CrossSuiTangBattleResult;
import com.yanqu.road.entity.activity.suitang.entity.battle.CrossSuiTangBattlefield;
import com.yanqu.road.entity.activity.suitang.entity.battle.CrossSuiTangBattlefieldRank;
import com.yanqu.road.entity.activity.suitang.entity.battle.CrossSuiTangBattlefieldTeam;
import com.yanqu.road.entity.activity.suitang.data.CrossSuiTangCity;
import com.yanqu.road.entity.activity.suitang.data.CrossSuiTangCityEvent;
import com.yanqu.road.entity.activity.suitang.entity.city.CrossSuiTangCollect;
import com.yanqu.road.entity.activity.suitang.entity.group.CrossSuiTangGroup;
import com.yanqu.road.entity.activity.suitang.entity.rank.CrossSuiTangRank;
import com.yanqu.road.entity.activity.suitang.entity.rank.CrossSuiTangRankListModel;
import com.yanqu.road.entity.activity.suitang.entity.team.CrossSuiTangTeam;
import com.yanqu.road.entity.activity.suitang.entity.union.CrossSuiTangCommanderData;
import com.yanqu.road.entity.activity.suitang.entity.union.CrossSuiTangUnionJoinMember;
import com.yanqu.road.entity.activity.suitang.entity.union.CrossSuiTangUnionRound;
import com.yanqu.road.entity.activity.suitang.entity.user.CrossSuiTangUserBuGaoCount;
import com.yanqu.road.entity.activity.suitang.entity.user.CrossSuiTangUserRound;
import com.yanqu.road.entity.activity.suitang.enums.*;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eSceneType;
import com.yanqu.road.entity.guess.CommonGuessInitReq;
import com.yanqu.road.entity.guess.CommonGuessRewardItem;
import com.yanqu.road.entity.guess.emuns.CommonGuessPlayTypeEnum;
import com.yanqu.road.entity.guess.emuns.CommonGuessTypeEnum;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.rank.yrank.UnionYRank;
import com.yanqu.road.entity.rank.yrank.UserYRank;
import com.yanqu.road.entity.scene.ScenePlayerInfo;
import com.yanqu.road.entity.scene.UserScene;
import com.yanqu.road.entity.union.UnionBaseInfo;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroupUnion;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroupUser;
import com.yanqu.road.logic.bussiness.activity.SuiTangActivityBusiness;
import com.yanqu.road.logic.helper.UnionHelper;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.activity.suitang.SuiTang;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.pb.rank.RankProto;
import com.yanqu.road.pb.union.UnionProto;
import com.yanqu.road.server.TempServer;
import com.yanqu.road.server.manager.activity.ActivityMgr;
import com.yanqu.road.server.manager.activity.suitang.manager.*;
import com.yanqu.road.server.manager.activity.suitang.task.impl.*;
import com.yanqu.road.server.manager.guess.CrossCommonGuessMgr;
import com.yanqu.road.server.manager.scene.CrossSceneMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.manager.yrank.CrossYRankCacheMgr;
import com.yanqu.road.server.manager.yrank.CrossYRankMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.ConfigHelper;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.executor.ScheduledThreadPoolHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

public class CrossSuiTangActivity extends CrossSuiTangBaseActivity {

    private RandomHelper randomHelper = new RandomHelper();

    private int groupId;

    private int taskNum = 3;

    /*
     * 活动总数据
     */
    private CrossSuiTangData crossSuiTangData;

    /*
     * 商会数据
     */
    private Map<String, CrossSuiTangUnionData> unionDataMap = new ConcurrentHashMap<>();

    /*
     * 商会锁名单数据
     */
    private Map<String, CrossSuiTangUnionJoinData> unionJoinDataMap = new ConcurrentHashMap<>();

    /*
     * 玩家数据
     */
    private Map<Long, CrossSuiTangUserData> userDataMap = new ConcurrentHashMap<>();

    /**
     * 城池战报
     */
    private Map<String, List<CrossSuiTangCityWarReportData>> cityWarReportMap = new ConcurrentHashMap<>();

    /*
     * 个人战报
     */
    private Map<Long, List<CrossSuiTangUserWarReportData>> userWarReportDataMap = new ConcurrentHashMap<>();

    /*
     * 安民布告
     */
    private Map<String, Map<Long, CrossSuiTangUnionBuGaoData>> buGaoMap = new ConcurrentHashMap<>();
    /*
     * 玩家布告数量统计，不入库
     */
    private Map<Long, CrossSuiTangUserBuGaoCount> userBuGaoMap = new ConcurrentHashMap<>();
    /*
     * 玩家布告数量统计（领取），不入库
     */
    private Map<Long, CrossSuiTangUserBuGaoCount> userBuGaoForGetMap = new ConcurrentHashMap<>();

    // ============================== 缓存数据 ==============================
    // 待入库战报
    private List<CrossSuiTangUserWarReportData> needInsertUserReportList = new ArrayList();
    private List<CrossSuiTangCityWarReportData> needInsertCityReportList = new ArrayList();

    // 榜单
    private Map<eSuiTangWarType, Map<Integer, CrossSuiTangRankListModel>> warUnionRankMap = new ConcurrentHashMap<>(); // 战场内各个组商会榜
    private Map<eSuiTangWarType, Map<Integer, Map<Integer, Map<String, CrossSuiTangRankListModel>>>> warUserRankMap = new ConcurrentHashMap<>(); // 战场内各个组各个城池战斗的军功个人榜

    // 管理器
    private CrossSuiTangRoundActivityMgr roundActivityMgr = new CrossSuiTangRoundActivityMgr();
    private CrossSuiTangCityActivityMgr cityActivityMgr = new CrossSuiTangCityActivityMgr();
    private CrossSuiTangGroupActivityMgr groupActivityMgr = new CrossSuiTangGroupActivityMgr();
    private CrossSuiTangLockMemberMgr lockMemberMgr = new CrossSuiTangLockMemberMgr();
    private CrossSuiTangMapActivityMgr mapActivityMgr = new CrossSuiTangMapActivityMgr();
    private CrossSuiTangUnionActivityMgr unionActivityMgr = new CrossSuiTangUnionActivityMgr();
    private CrossSuiTangBarracksActivityMgr barracksActivityMgr = new CrossSuiTangBarracksActivityMgr();
    private CrossSuiTangBattleActivityMgr battleActivityMgr = new CrossSuiTangBattleActivityMgr();
    private CrossSuiTangSyncActivityMgr syncActivityMgr = new CrossSuiTangSyncActivityMgr();
    private CrossSuiTangRankActivityMgr rankActivityMgr = new CrossSuiTangRankActivityMgr();
    private CrossSuiTangLogActivityMgr logActivityMgr = new CrossSuiTangLogActivityMgr();
    private CrossSuiTangNpcTestActivityMgr npcTestActivityMgr = new CrossSuiTangNpcTestActivityMgr();

    public CrossSuiTangActivity(ActivityInfo activityInfo, int groupId) {
        super(activityInfo);
        this.groupId = groupId;

        // 数据
        crossSuiTangData = SuiTangActivityBusiness.getCrossSuiTangData(activityInfo.getActivityId(), groupId);
        if (crossSuiTangData == null) {
            crossSuiTangData = new CrossSuiTangData();
            crossSuiTangData.setActivityId(activityInfo.getActivityId());
            crossSuiTangData.setGroupId(groupId);
            crossSuiTangData.setBattleRound(new AtomicInteger(calcRoundMain()));
            crossSuiTangData.setStep(eSuiTangStage.NoStart);
            crossSuiTangData.setLockUnion(false);
            crossSuiTangData.setInsertOption();
        } else {
            crossSuiTangData.setCityMap(SuiTangActivityBusiness.getCrossSuiTangCity(activityInfo.getActivityId(), groupId));
            crossSuiTangData.setCityEventMap(SuiTangActivityBusiness.getCrossSuiTangCityEvent(activityInfo.getActivityId(), groupId));
        }
        unionJoinDataMap = SuiTangActivityBusiness.getCrossSuiTangUnionJoinDataMap(activityInfo.getActivityId(), groupId);
        unionDataMap = SuiTangActivityBusiness.getCrossSuiTangUnionDataMap(activityInfo.getActivityId(), groupId);
        buGaoMap = SuiTangActivityBusiness.getCrossSuiTangUnionBuGaoDataMap(activityInfo.getActivityId(), groupId);
        userDataMap = SuiTangActivityBusiness.getCrossUserData(activityInfo.getActivityId(), groupId);
        cityWarReportMap = SuiTangActivityBusiness.getCityReportList(activityInfo.getActivityId(), groupId, config.getParamConfig().getSuiTangCityBattleReportNumLimit());
        userWarReportDataMap = SuiTangActivityBusiness.getUserReportList(activityInfo.getActivityId(), groupId, config.getParamConfig().getSuiTangPersonalBattleReportNumLimit());

        // 管理器
        roundActivityMgr.setActivity(this);
        cityActivityMgr.setActivity(this);
        groupActivityMgr.setActivity(this);
        lockMemberMgr.setActivity(this);
        mapActivityMgr.setActivity(this);
        unionActivityMgr.setActivity(this);
        barracksActivityMgr.setActivity(this);
        battleActivityMgr.setActivity(this);
        syncActivityMgr.setActivity(this);
        rankActivityMgr.setActivity(this);
        logActivityMgr.setActivity(this);
        npcTestActivityMgr.setActivity(this);

        // 初始化管理
        cityActivityMgr.init();
        battleActivityMgr.init();

        // 初始化
        if (unionJoinDataMap.size() != unionDataMap.size()) {
            getUnionActivityMgr().initUnionData();
        }
        initAllRankList();
        initUserBuGaoNumMap();

        // 启动线程
        initTask();
        thread.start();
        //TempServer.getTimerExecutorService().scheduleWithFixedDelay(new TimerRun(), 0, 1, TimeUnit.MILLISECONDS);
    }

    public void reloadConfig() {
        loadConfigFromDb(config.getActivityInfo());
    }

    /**
     * 初始化所有Task
     */
    public void initTask() {
        TempServer.getTimerExecutorService().scheduleWithFixedDelay(new CrossSuiTangMainTask(this), 0, 1, TimeUnit.SECONDS);
        TempServer.getTimerExecutorService().scheduleWithFixedDelay(new CrossSuiTangRefreshCityEventTask(this), 0, 1, TimeUnit.SECONDS);
        for (int i = 0; i < taskNum; i++) {
            TempServer.getTimerExecutorService().scheduleWithFixedDelay(new CrossSuiTangAutoBattleTask(this, i), 0, 100, TimeUnit.MILLISECONDS);
            TempServer.getTimerExecutorService().scheduleWithFixedDelay(new CrossSuiTangCityTask(this, i), 0, 100, TimeUnit.MILLISECONDS);
        }
        TempServer.getTimerExecutorService().scheduleWithFixedDelay(new CrossSuiTangCityTeamRecoveryTask(this), 0, 1, TimeUnit.SECONDS);
        TempServer.getTimerExecutorService().scheduleWithFixedDelay(new CrossSuiTangMoveTask(this), 0, 1, TimeUnit.SECONDS);
        TempServer.getTimerExecutorService().scheduleWithFixedDelay(new CrossSuiTangBarracksRecoveryTask(this), 0, 60, TimeUnit.SECONDS);
        TempServer.getTimerExecutorService().scheduleWithFixedDelay(new CrossSuiTangSyncCityTask(this), 0, 1000, TimeUnit.MILLISECONDS);
    }

    /**
     * 初始化全部榜单
     */
    private void initAllRankList() {
        for (CrossSuiTangUnionJoinData join : unionJoinDataMap.values()) {
            CrossSuiTangUnionData unionData = unionDataMap.get(join.getUnionUid());
            CrossSuiTangUnionRound unionRound = unionData.getUnionRoundMap().get(calcRound());
            long totalScore = unionRound == null ? 0 : unionRound.getCurrentCityScore().longValue();

            // 初始化战场内榜单
            if (unionRound == null) {
                getRankActivityMgr().initWarUnionRank(join.getUnionUid(), totalScore, System.currentTimeMillis());
            } else {
                getRankActivityMgr().initWarUnionRank(join.getUnionUid(), totalScore, unionRound.isOutTime());
            }

        }
    }

    public void onRun() {
        // 活动主调度
        if (config == null) {
            //addTask(new CrossSuiTangMainTask(this, System.currentTimeMillis() + DateHelper.SECOND_MILLIONS));
            return;
        }
        eSuiTangStage oldStep = this.getCrossSuiTangData().getStep();
        AtomicInteger oldRound = this.getCrossSuiTangData().getBattleRound();
        eSuiTangStage newStep = config.getSuiTangStage();
        int newRound = calcRoundMain();

        logger.debug("activity:{},step:{},round:{},groupId:{}", config.getActivityId(), newStep.name(), newRound, groupId);

        if (oldStep != newStep || newRound != oldRound.get()) {
            this.getCrossSuiTangData().setStep(newStep);
            this.getCrossSuiTangData().setBattleRound(new AtomicInteger(newRound));
            if (newStep == eSuiTangStage.ReadyTime) {
                handleLockUnion();
            }
            if (newStep == eSuiTangStage.Stage1Time || newStep == eSuiTangStage.Stage1RestTime) {
                if (oldRound.intValue() != newRound) {
                    handleRoundChang();
                }
            }
            if (newStep == eSuiTangStage.Stage1RestTime || newStep == eSuiTangStage.WaitRewardTime) {
                // 结算
                if (oldRound.intValue() == newRound) {
                    rankActivityMgr.settle(newStep);
                }
            }
        }

        //领奖期触发
        if (oldStep != newStep) {
            if (newStep == eSuiTangStage.RewardTime) {
                //注入竞猜结果
                this.updateGuessRandResult();
                // 补发自动设置元宝
                this.autoSettingSendReward();
            }
        }

        if (newStep == eSuiTangStage.JoinTime) {
            // 未到时间，更新下锁名单
            lockMemberMgr.lockUnion();
        }

        if (newStep.getValue() >= eSuiTangStage.ReadyTime.getValue() && !crossSuiTangData.getLockUnion()) {
            handleLockUnion();
        }

        if (newStep.getValue() >= eSuiTangStage.Stage1Time.getValue()
                && newStep.getValue() <= eSuiTangStage.Stage1EndTime.getValue()
                && (crossSuiTangData.getActGroupMap().get(newRound) == null
                || crossSuiTangData.getActGroupMap().get(newRound).isEmpty())
        ) {
            handleRoundChang();
        }

        //addTask(new CrossSuiTangMainTask(this, System.currentTimeMillis() + DateHelper.SECOND_MILLIONS));
    }

    private void handleRoundChang() {
        groupActivityMgr.groupUnion();
        // 分组完成，才进行下一步
        if (crossSuiTangData.getActGroupMap().get(calcRound()) != null && !crossSuiTangData.getActGroupMap().get(calcRound()).isEmpty()) {
            roundActivityMgr.OnRoundChange();
            rankActivityMgr.resetWarUnionRank();
            barracksActivityMgr.init();
            cityActivityMgr.init();
            mapActivityMgr.init();
            unionActivityMgr.resetUnionInfo();
            userWarReportDataMap.clear();
            cityWarReportMap.clear();
            logActivityMgr.addGroupLog();
        }
    }

    private void handleLockUnion() {
        // 进入准备期，锁名单
        if (this.lockMemberMgr.lockUnion()) {
            // 初始化商会活动数据
            unionActivityMgr.initUnionData();
            // 初始化轮次数据
            roundActivityMgr.init();
            // 初始化兵营数据
            barracksActivityMgr.init();
            // 初始化城市数据
            cityActivityMgr.init();
            // 初始化商会战场榜单数据
            rankActivityMgr.initWarUnionRank();
            // 记录分组日志
            logActivityMgr.addGroupLog();
            // 记录锁定日志
            logActivityMgr.addLockLog();
            //初始化竞猜数据
            this.initGuessData();
        }
    }

    /**
     * 初始化竞猜数据
     */
    public void initGuessData() {
        //开始时间
        long startTime = System.currentTimeMillis();
        //结束时间
        List<Integer> betList = config.getParamConfig().getSuiTangBetStageTime();
        if (betList == null || betList.size() < 2) {
            logger.error("隋唐竞猜初始化-竞猜时间配置错误：{}", betList);
            return;
        }
        int day = betList.get(0) - 1;
        int hour = betList.get(1);
        //竞猜操作结束时间
        long endTime = config.getActivityInfo().getBeginShowTime() * 1000 + day * DateHelper.DAY_MILLIONS + hour * DateHelper.HOUR_MILLIONS;
        //等待结果结束时间
        long endWaitResultTime = config.getActivityInfo().getEndTime() * 1000 + 5 * DateHelper.MINUTE_MILLIONS;
        //展示结束时间
        long endShowTime = config.getActivityInfo().getEndShowTime() * 1000;
        //选项LIST
        List<String> objIdList = new ArrayList<>();
        for (CrossSuiTangUnionJoinData unionJoinData : unionJoinDataMap.values()) {
            objIdList.add(unionJoinData.getUnionUid());
        }
        //奖励list
        List<CommonGuessRewardItem> rewardList = new ArrayList<>();
        for (SuiTangGuessConfig suiTangGuessConfig : config.getGuessConfigMap().values()) {
            CommonGuessRewardItem item = new CommonGuessRewardItem();
            item.setId(suiTangGuessConfig.getId());
            item.setReward(suiTangGuessConfig.getRewards());
            item.setName(suiTangGuessConfig.getName());
            rewardList.add(item);
        }
        //初始化
        CommonGuessInitReq req = new CommonGuessInitReq();
        req.setActivityId(config.getActivityId());
        req.setGroupId(getGroupId());
        req.setRound(0);
        req.setSiteId(0);
        req.setTypeEnum(CommonGuessTypeEnum.TYPE_UNION);
        req.setPlayTypeEnum(CommonGuessPlayTypeEnum.PLAY_TYPE_TOP_THREE);
        req.setStartTime(startTime);
        req.setEndTime(endTime);
        req.setEndWaitResultTime(endWaitResultTime);
        req.setEndShowTime(endShowTime);
        req.setObjIdList(objIdList);
        req.setRewardList(rewardList);
        CrossCommonGuessMgr.initData(req);
    }

    /**
     * 注入竞猜结果
     */
    private void updateGuessRandResult() {
        List<UnionYRank> rankList = CrossYRankMgr.getSortUnionRankList(config.getActivityId(), getGroupId(), String.valueOf(eGamePlayerEventType.SuiTangUnionScoreRank.getValue()));
        List<String> unionRankList = new ArrayList<>();
        for (UnionYRank unionYRank : rankList) {
            unionRankList.add(unionYRank.getUnionUid());
        }
        CrossCommonGuessMgr.updateRankResult(config.getActivityId(), getGroupId(), 0, 0, unionRankList);
    }


    /**
     * 自动设置补发元宝
     */
    public void autoSettingSendReward() {
        for (CrossSuiTangUserData userData : userDataMap.values()) {
            if (userData == null) {
                continue;
            }
            // 剩余元宝次数
            long leftIngotsTimes = 0;
            synchronized (getMapActivityMgr().getPlayerLock(userData.getUserId())) {
                CrossSuiTangAutoSettingData autoSettingData = userData.getAutoSettingData();
                if (autoSettingData == null) {
                    continue;
                }
                leftIngotsTimes = autoSettingData.getIngotsTimes();
                if (leftIngotsTimes <= 0) {
                    continue;
                }
                // 清空
                autoSettingData.setIngotsTimes(0);
                userData.setUpdateOption();
            }


            SuiTang.CrossSuiTangAutoSettingIngotOperateFromCrossMsg.Builder respMsg = SuiTang.CrossSuiTangAutoSettingIngotOperateFromCrossMsg.newBuilder();
            respMsg.setRet(0);
            respMsg.setUserId(userData.getUserId());
            respMsg.setOperateType(2);
            respMsg.setOffsetIngotsTimes(leftIngotsTimes);
            // 清空元宝次数
            respMsg.setIngotsTimes(0);
            sendPacket(GameProtocol.S_SUI_TANG_AUTO_SETTING_INGOTS_OPERATE_FROM_CROSS, respMsg, userData.getUserId());
        }
    }

    /*
     * unionUpdate 商会发生成员、职位变化
     */
    public void unionUpdate(UnionActivityGroupUnion union) {
        List<Long> syncUserList = new ArrayList<>();
        for (UnionActivityGroupUser groupUser : union.getUserMap().values()) {
            Map<Long, CrossSuiTangUnionJoinMember> memberMap = lockMemberMgr.getUnionJoin(union.getUnionUid()).getMemberMap();
            if (!memberMap.containsKey(groupUser.getUserId()) || memberMap.get(groupUser.getUserId()).getPosition() != groupUser.getPosition()) {
                syncUserList.add(groupUser.getUserId());
            }
        }

        lockMemberMgr.updateUnion(union);
        lockMemberMgr.checkUnionJoinMember(union.getUnionUid());
        unionActivityMgr.onUnionChange(union.getUnionUid(), syncUserList);

        for (Long userId : syncUserList) {
            roundActivityMgr.initUserRoundData(userId);
            barracksActivityMgr.refreshTeam(getUserData(userId));
            syncActivityMgr.syncBaseDataMsg(userId);
            syncActivityMgr.syncUserDataToGameServer(getUserData(userId));
            //logActivityMgr.addLockJoinLog(union.getUnionUid(), userId);
            CrossSuiTangUnionRound roundData = unionActivityMgr.getUnionRoundData(union.getUnionUid());
            if (roundData != null) {
                syncActivityMgr.notifyConditionChange(userId, eGamePlayerEventType.SuiTangUnionZhanLingZC, roundData.getUnionTaskMap().getOrDefault(eGamePlayerEventType.SuiTangUnionZhanLingZC.getValue(), 0), "");
                syncActivityMgr.notifyConditionChange(userId, eGamePlayerEventType.SuiTangUnionZhanLingGC, roundData.getUnionTaskMap().getOrDefault(eGamePlayerEventType.SuiTangUnionZhanLingGC.getValue(), 0), "");
                syncActivityMgr.notifyConditionChange(userId, eGamePlayerEventType.SuiTangUnionZhanLingXC, roundData.getUnionTaskMap().getOrDefault(eGamePlayerEventType.SuiTangUnionZhanLingXC.getValue(), 0), "");
            }
        }
        syncActivityMgr.syncCommanderInfoToUnion(union.getUnionUid());
        //syncActivityMgr.notifyConditionChangeToUnion(union.getUnionUid(), eGamePlayerEventType.SuiTangUnionZhanLingGC, 1, "");
    }

    public void save() {
        if (crossSuiTangData.isInsertOption()) {
            SuiTangActivityBusiness.addCrossSuiTangData(crossSuiTangData);
        } else if (crossSuiTangData.isUpdateOption()) {
            SuiTangActivityBusiness.updateCrossSuiTangData(crossSuiTangData);
        }

        saveCity();

        saveCityEvent();

        for (CrossSuiTangUnionData unionData : unionDataMap.values()) {
            if (unionData.isInsertOption()) {
                SuiTangActivityBusiness.addCrossSuiTangUnionData(unionData);
            } else if (unionData.isUpdateOption()) {
                SuiTangActivityBusiness.updateCrossSuiTangUnionData(unionData);
            }
        }

        for (Map<Long, CrossSuiTangUnionBuGaoData> buGaoDataMap : buGaoMap.values()) {
            for (CrossSuiTangUnionBuGaoData buGaoData : buGaoDataMap.values()) {
                if (buGaoData.isInsertOption()) {
                    SuiTangActivityBusiness.addCrossSuiTangUnionBuGaoData(buGaoData);
                } else if (buGaoData.isUpdateOption()) {
                    SuiTangActivityBusiness.updateCrossSuiTangUnionBuGaoData(buGaoData);
                }
            }
        }

        for (CrossSuiTangUnionJoinData unionJoinData : unionJoinDataMap.values()) {
            if (unionJoinData.isInsertOption()) {
                SuiTangActivityBusiness.addCrossSuiTangUnionJoinData(unionJoinData);
            } else if (unionJoinData.isUpdateOption()) {
                SuiTangActivityBusiness.updateCrossSuiTangUnionJoinData(unionJoinData);
            }
        }

        for (CrossSuiTangUserData userData : userDataMap.values()) {
            if (npcTestActivityMgr.isNpc(userData.getUserId())) {
                continue;
            }
            if (userData.isInsertOption()) {
                SuiTangActivityBusiness.addCrossSuiTangUserData(userData);
            } else if (userData.isUpdateOption()) {
                SuiTangActivityBusiness.updateCrossSuiTangUserData(userData);
            }
        }

        List<CrossSuiTangCityWarReportData> tempNeedInsertCityReportList;
        synchronized (needInsertCityReportList) {
            tempNeedInsertCityReportList = new ArrayList<>(needInsertCityReportList);
            needInsertCityReportList.clear();
        }
        if (tempNeedInsertCityReportList.size() > 0) {
            SuiTangActivityBusiness.addCityReportList(tempNeedInsertCityReportList);
        }

        List<CrossSuiTangUserWarReportData> tempNeedInsertUserReportList;
        synchronized (needInsertUserReportList) {
            tempNeedInsertUserReportList = new ArrayList<>(needInsertUserReportList);
            needInsertUserReportList.clear();
        }
        if (tempNeedInsertUserReportList.size() > 0) {
            SuiTangActivityBusiness.addUserReportList(tempNeedInsertUserReportList);
        }

        // 日志保存
        try {
            //SuiTangActivityLog.save();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * loginByCmd
     */
    public void loginByCmd(long userId, SuiTang.CrossSuiTangLoginReqMsg reqMsg) {
        if (isAble(userId)) {
            // 退出一下场景
            CrossSceneMgr.quitScene(userId, System.currentTimeMillis());

            CrossSuiTangUserData userData = getUserData(userId);
            // 尝试初始化一下玩家的轮次数据
            if (config.getSuiTangStage().getValue() < eSuiTangStage.RewardTime.getValue()) {
                // 第一次帮他同步
                if (userData.getPatronsTotalAbility() == 0) {
                    firstSyncPatrons(userData, reqMsg.getTotalAbility(), reqMsg.getSoldierAddition(), reqMsg.getPatronsNSum(), reqMsg.getPatronsTotalNum());
                }
            }
            // 跨服同步用户数据到游戏服
            syncActivityMgr.syncUserDataToGameServer(userData);
            // 同步战功成就
            syncActivityMgr.notifyConditionChange(userId, eGamePlayerEventType.SuiTangUserZhanGong, userData.getZhanGong(), "");
            // 同步商会任务成就
            CrossSuiTangUnionRound roundData = unionActivityMgr.getUnionRoundData(userData.getUnionUid());
            if (roundData != null) {
                syncActivityMgr.notifyConditionChange(userId, eGamePlayerEventType.SuiTangUnionZhanLingZC, roundData.getUnionTaskMap().getOrDefault(eGamePlayerEventType.SuiTangUnionZhanLingZC.getValue(), 0), "");
                syncActivityMgr.notifyConditionChange(userId, eGamePlayerEventType.SuiTangUnionZhanLingGC, roundData.getUnionTaskMap().getOrDefault(eGamePlayerEventType.SuiTangUnionZhanLingGC.getValue(), 0), "");
                syncActivityMgr.notifyConditionChange(userId, eGamePlayerEventType.SuiTangUnionZhanLingXC, roundData.getUnionTaskMap().getOrDefault(eGamePlayerEventType.SuiTangUnionZhanLingXC.getValue(), 0), "");
            }
            // 同步民心
            syncActivityMgr.syncRedPacketBoxValue(userData.getUnionUid());
            // 同步阵营指挥官
            syncActivityMgr.syncCommanderInfo(userId, userData.getUnionUid());
            // 同步全部红点
            SuiTang.SuiTangSyncRedDotRespMsg.Builder builder = SuiTang.SuiTangSyncRedDotRespMsg.newBuilder();
            builder.addAllType(userData.getRedDotMap().keySet());
            sendPacket(ClientProtocol.U_SUI_TANG_SYNC_RED_DOT, builder, userData.getUserId());
        }

        // 同步数据
        syncActivityMgr.syncBaseDataMsg(userId);
    }

    /*
     * 首次同步战力
     */
    public void firstSyncPatrons(CrossSuiTangUserData userData, long patronsTotalAbility, long addition, long patronsNSum, int patronsTotalNum) {
        barracksActivityMgr.syncPatrons(userData.getUserId(), true, patronsTotalAbility, addition, patronsNSum, patronsTotalNum, false);
        if (userData.getTeam().getCityId() != 0) {
            // 加入
            CrossSuiTangCity curCity = cityActivityMgr.getCurCity(userData.getUserId(), userData.getTeam().getCityId());
            cityActivityMgr.addCityDefTeamMap(userData.getUserId(), cityActivityMgr.getCurCity(userData.getUserId(), userData.getTeam().getCityId()));
            syncActivityMgr.syncCity(curCity, false);
            syncActivityMgr.syncBattleResultMsg(curCity);
        }
    }

    private ScheduledExecutorService debugExecutorService = null;

    /*
     * debug
     */
    public void debug(long userId, String code, String param) {
        if (ConfigHelper.getInt("channelId") != 666) {
            return;
        }
        CrossSuiTangUserData userData = getUserData(userId);
        if (userData == null) {
            return;
        }
        // 生成npc
        if (code.equals("/stgroup")) {
            groupActivityMgr.groupUnion();
        } else if (code.equals("/stnpcmode")) {
            npcTestActivityMgr.setNpcMode(true);
        } else if (code.equals("/stresetround")) {
            handleRoundChang();
        } else if (code.equals("/stlock")) {
            handleLockUnion();
        } else if (code.equals("/stinitcity")) {
            crossSuiTangData.getCityMap().clear();
            cityActivityMgr.init();
        } else if (code.equals("/stinitbarracks")) {
            barracksActivityMgr.init();
        } else if (code.equals("/stinitcityevent")) {
            cityActivityMgr.refreshCityEvent();
        } else if (code.equals("/strteam")) {
            barracksActivityMgr.refreshTeam(getUserData(userId));
        } else if (code.equals("/stlock")) {
            lockMemberMgr.lockUnion();
        } else if (code.equals("/stresetsync")) {
            userData.setLastSyncPatronsTime(0);
            syncActivityMgr.syncBaseDataMsg(userId);
        } else if (code.equals("/stresetwarrank")) {
            rankActivityMgr.resetWarUnionRank();
        } else if (code.equals("/sttask")) {
            AllTask();
        } else if (code.equals("/stsynccityevent")) {
            syncActivityMgr.syncCityEvent();
        } else if (code.equals("/staddminxin")) {
            CrossSuiTangUnionData unionData = unionActivityMgr.getUnionData(getUserData(userId).getUnionUid());
            unionData.setRedPacketValue(unionData.getRedPacketValue() + StringUtils.parseInt(param));
            syncActivityMgr.syncRedPacketBoxValue(unionData.getUnionUid());
        } else if (code.equals("/staddzg")) {
            userData.setZhanGong(StringUtils.parseInt(param));
            syncActivityMgr.notifyConditionChange(userId, eGamePlayerEventType.SuiTangUserZhanGong, StringUtils.parseInt(param), "");
        } else if (code.equals("/staddjz")) {
            SuiTang.CrossSuiTangCityFoodCollectRespMsg.Builder builder = SuiTang.CrossSuiTangCityFoodCollectRespMsg.newBuilder();
            builder.setRet(0);
            String reward = config.getParamConfig().getJunZiItem() + "=" + StringUtils.parseInt(param);
            builder.setReward(reward);
            sendPacket(GameProtocol.S_CROSS_SUI_TANG_CITY_FOOD_COLLECT, builder, userId);
        } else if (code.equals("/stallcity")) {
            for (CrossSuiTangCity city : cityActivityMgr.getCurCityMap(userId).values()) {
                if (city.getCityId() == 6001 || city.getCityId() == 2001) {
                    continue;
                }
                String unionUid = getUserData(userId).getUnionUid();
                // 城池被攻占
                city.setUnionId(unionUid);
                // 重新初始化战场
                cityActivityMgr.handleCityChangeUnion(city, "");
                cityActivityMgr.handleCityEventChangeUnion(city, "");
                cityActivityMgr.handleCityTypeBuffsChangeUnion(city, "");
            }
        } else if (code.equals("/stcitynull")) {
            CrossSuiTangCity curCity = getCityActivityMgr().getCurCity(userId, StringUtils.parseInt(param));
            String unionId = curCity.getUnionId();
            // 城池被攻占
            curCity.setUnionId("");
            // 重新初始化战场
            cityActivityMgr.handleCityChangeUnion(curCity, unionId);
            cityActivityMgr.handleCityEventChangeUnion(curCity, unionId);
            cityActivityMgr.handleCityTypeBuffsChangeUnion(curCity, unionId);
        } else if (code.equals("/stcityset")) {
            CrossSuiTangCity curCity = getCityActivityMgr().getCurCity(userId, StringUtils.parseInt(param));
            String unionId = curCity.getUnionId();
            // 城池被攻占
            curCity.setUnionId(getUserData(userId).getUnionUid());
            // 重新初始化战场
            cityActivityMgr.handleCityChangeUnion(curCity, unionId);
            cityActivityMgr.handleCityEventChangeUnion(curCity, unionId);
            cityActivityMgr.handleCityTypeBuffsChangeUnion(curCity, unionId);
        } else if (code.equals("/staddsoldier")) {
            CrossSuiTangBarracks barracks = getUserData(userId).getBarracks();
            if (barracks == null) {
                barracks = new CrossSuiTangBarracks();
                barracks.setReadyMaxNum(10000);
                barracks.setCreateSpeed(100);
            }
            barracks.setReadyNum(StringUtils.parseInt(param));
        } else if (code.equals("/stsetteamsoldier")) {
            CrossSuiTangTeam team = getUserData(userId).getTeam();
            team.setSoldierNum(StringUtils.parseInt(param));
            syncActivityMgr.syncTeamToSelf(team);
        } else if (code.equals("/stclearbattlelist")) {
            CrossSuiTangTeam team = getUserData(userId).getTeam();
            CrossSuiTangUserRound curUserRound = battleActivityMgr.getCurUserRound(userId);
            battleActivityMgr.crossSuiTangCityTask(team.getCityId(), curUserRound.getWarType(), curUserRound.getActGroupId());
        } else if (code.startsWith("/stcmd")) {
            if (param.equals("29411")) {
                getDataByCmd(userId, false, eSuiTangWarType.WAR_TYPE_YIJUN, 1, 1, 1, null);
            } else if (param.equals("29435")) {
                SuiTang.SuiTangCityReqMsg.Builder builder = SuiTang.SuiTangCityReqMsg.newBuilder();
                SuiTang.SuiTangSyncCityMsg.Builder builder1 = SuiTang.SuiTangSyncCityMsg.newBuilder();
                builder1.setCityId(1001);
                builder1.setTime(System.currentTimeMillis());
                builder.addCityInfo(builder1);
                getCityTeamByCmd(userId, builder.build());
            } else if (param.equals("29423")) {
                SuiTang.SuiTangAttackReqMsg.Builder builder = SuiTang.SuiTangAttackReqMsg.newBuilder();
                builder.setCityId(2023);
                builder.setTeamNo(1);
                attackByCmd(userId, builder.build());
            }
        } else if (code.equals("/stnpcstart")) {
            // 开多个线程同时并发跑
            int core = 12;
            debugExecutorService = ScheduledThreadPoolHelper.createGameScheduledThreadPoolExecutor(core, "隋唐-npc-");
            for (int i = 0; i < core; i++) {
                debugExecutorService.scheduleWithFixedDelay(new CrossSuiTangNpcTask(this, core, i), 0, 1000, TimeUnit.MILLISECONDS);
            }
        } else if (code.equals("/stnpcstop")) {
            debugExecutorService.shutdown();
        } else if (code.equals("/staddnpc")) {
            npcTestActivityMgr.addNpc(Integer.parseInt(param));
        }
    }

    /*
     * changeSoldier
     */
    public void changeSoldier(long userId, SuiTang.CrossSuiTangChangeTeamSoldierReqMsg reqMsg) {
        SuiTang.SuiTangChangeTeamSoldierRespMsg.Builder respMsg = SuiTang.SuiTangChangeTeamSoldierRespMsg.newBuilder();
//        if (battleActivityMgr.isOut(userId)) {
//            respMsg.setRet(GameErrorCode.E_SUI_TANG_IS_OUT);
//            respMsg.setTeam(parseSuiTangTeamMsg(barracksActivityMgr.getTeam(userId)));
//            respMsg.setBarracks(parseSuiTangBarracksMsg(userId));
//            sendPacket(ClientProtocol.U_SUI_TANG_CHANGE_TEAM_SOLDIER, respMsg, userId);
//            return;
//        }

        int ret = barracksActivityMgr.changeSoldier(userId, reqMsg.getChange().getSoldierNum());
        respMsg.setRet(ret);
        respMsg.setTeam(parseSuiTangTeamMsg(barracksActivityMgr.getTeam(userId)));
        respMsg.setBarracks(parseSuiTangBarracksMsg(userId));
        sendPacket(ClientProtocol.U_SUI_TANG_CHANGE_TEAM_SOLDIER, respMsg, userId);
    }

    /*
     * getUserBarracksInfo
     */
    public void getUserBarracksInfo(long userId) {
        barracksActivityMgr.barracksCalc(userId);
        SuiTang.SuiTangGetBarracksRespMsg.Builder respMsg = SuiTang.SuiTangGetBarracksRespMsg.newBuilder();
        if (!isAble(userId)) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_GET_BARRACKS, respMsg, userId);
            return;
        }
        respMsg.setRet(0);
        respMsg.setBarracks(parseSuiTangBarracksMsg(userId));
        sendPacket(ClientProtocol.U_SUI_TANG_GET_BARRACKS, respMsg, userId);
    }

    /*
     * getBattleFieldByCmd
     */
    public void getBattleFieldByCmd(long userId, SuiTang.SuiTangEnterBattlefieldReqMsg reqMsg) {
        int ret = getBattleField(userId, reqMsg.getCityId());
        if (ret != 0) {
            SuiTang.SuiTangEnterBattlefieldRespMsg.Builder builder = SuiTang.SuiTangEnterBattlefieldRespMsg.newBuilder();
            builder.setRet(ret);
            sendPacket(ClientProtocol.U_SUI_TANG_GET_BATTLE_FIELD, builder, userId);
        }
    }

    /*
     * updateUnionMemberByCmd
     */
    public void updateUnionMemberByCmd(SuiTang.CrossSuiTangGetMemberRespMsg reqMsg) {
        synchronized (lock) {
            if (ActivityMgr.activityInShowTime(config.getActivityInfo()))
                if (crossSuiTangData.getLockUnion()) {
                    return;
                }

            for (SuiTang.SuiTangUnionMemberMsg memberMsg : reqMsg.getMemberList()) {
                CrossSuiTangUnionJoinData join = unionJoinDataMap.get(memberMsg.getUnionUid());
                if (join == null || !join.getMemberMap().containsKey(memberMsg.getUserId())) {
                    continue;
                }

                CrossSuiTangUnionJoinMember member = join.getMemberMap().get(memberMsg.getUserId());
                member.setEarnSpeed(Long.valueOf(memberMsg.getEarnSpeed()));
                if (memberMsg.hasPatronsTopAbility() && Long.valueOf(memberMsg.getPatronsTopAbility()) > member.getTopAbility()) {
                    member.setTopAbility(Long.valueOf(memberMsg.getPatronsTopAbility()));
                    join.reCalcAbility();
                }
                join.setUpdateOption();
            }
        }
    }

    /*
     * useMuBingLingByCmd
     */
    public void useMuBingLingByCmd(long userId, int goodsId, long count) {
//        if (battleActivityMgr.isOut(userId)) {
//            // 淘汰了不处理
//            return;
//        }

        int ret = barracksActivityMgr.useMuBingLing(userId, goodsId, count);
        if (ret != 0) {
            // 先扔个日志
            logger.error("useMuBingLing error,ret:{}", ret);
        }

        // 同步一下兵营
        SuiTang.SuiTangSyncBarracksRespMsg.Builder syncMsg = SuiTang.SuiTangSyncBarracksRespMsg.newBuilder();
        syncMsg.setBarracks(parseSuiTangBarracksMsg(userId));
        sendPacket(Protocol.U_SUI_TANG_SYNC_BARRACKS, syncMsg, userId);
    }

    /*
     * 任命指挥官
     */
    public void campCommanderAppoint(long userId, SuiTang.CrossSuiTangUnionCommanderAppointReqMsg reqMsg) {
        SuiTang.SuiTangUnionCommanderAppointRespMsg.Builder respMsg = SuiTang.SuiTangUnionCommanderAppointRespMsg.newBuilder();
        respMsg.setRet(0);
        CrossSuiTangUserData userData = getUserData(userId);
        CrossSuiTangUnionJoinData unionData = cityActivityMgr.getUnionJoin(userData.getUnionUid());
        if (unionData.getMasterId() != userId) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_CAN_NOT_SET_COMMANDER);
            sendPacket(ClientProtocol.U_SUI_TANG_CAMP_COMMANDER_APPOINT, respMsg, userId);
            return;
        }
        CrossSuiTangUserData appointUserData = getUserData(reqMsg.getUserId());//任命的玩家
        synchronized (lock) {
            // 只能任命当前阵营的人
            if (!Objects.equals(appointUserData.getUnionUid(), userData.getUnionUid())) {
                respMsg.setRet(GameErrorCode.E_SUI_TANG_COMMANDER_ONLY_SET_THE_SAME_CAMP);
                sendPacket(ClientProtocol.U_SUI_TANG_CAMP_COMMANDER_APPOINT, respMsg, userId);
                return;
            }
            CrossSuiTangUnionData suiTangUnionData = unionDataMap.get(userData.getUnionUid());
            CrossSuiTangCommanderData commanderData = suiTangUnionData.getCommanders();
            if (commanderData == null) {
                commanderData = new CrossSuiTangCommanderData();
            }
            if (!commanderData.getUserId().contains(userId)) {
                commanderData.getUserId().add(userId);  // 第一个是会长
            }
            if (commanderData.getUserId().size() == 2) {
                commanderData.getUserId().remove(commanderData.getUserId().size() - 1);
            }
            commanderData.getUserId().add(appointUserData.getUserId()); // 第二个是任命的玩家
            suiTangUnionData.setCommanders(commanderData);
            sendPacket(ClientProtocol.U_SUI_TANG_CAMP_COMMANDER_APPOINT, respMsg, userId);
            // 同步信息给阵营玩家
            syncActivityMgr.syncCommanderInfoToUnion(userData.getUnionUid());
            logActivityMgr.addCommandSetLog(unionData.getUnionUid());
        }
    }

    /**
     * 指挥官设置信息
     */
    public void commanderSet(long userId, SuiTang.CrossSuiTangCommanderSetReqMsg reqMsg) {
        SuiTang.SuiTangCommanderSetRespMsg.Builder respMsg = SuiTang.SuiTangCommanderSetRespMsg.newBuilder();
        respMsg.setRet(0);
        CrossSuiTangUserData userData = getUserData(userId);
        // 判断是否为指挥官
        synchronized (lock) {
            CrossSuiTangUnionData unionData = unionDataMap.get(userData.getUnionUid());
            CrossSuiTangCommanderData commanderData = unionData.getCommanders();
            if (commanderData == null) {
                commanderData = new CrossSuiTangCommanderData();
            }
            CrossSuiTangUnionJoinData unionJoinData = cityActivityMgr.getUnionJoin(userData.getUnionUid());
            // 只有会长和指挥官才可设置
            boolean isMaster = unionJoinData.getMasterId() == userId;
            boolean isCommander = commanderData.getUserId().contains(userId);
            if (!isMaster && !isCommander) {
                respMsg.setRet(GameErrorCode.E_SUI_TANG_NOT_COMMANDER);
                sendPacket(ClientProtocol.U_SUI_TANG_COMMANDER_SET, respMsg, userId);
                return;
            }

            SuiTang.SuiTangCommanderSetReqMsg commanderSetReqMsg = reqMsg.getCommanderSetReqMsg();
            if (commanderData.getMinorCityId() != 0 && commanderData.getMajorCityId() != 0) {
                if (commanderSetReqMsg.hasMajorCityId() && commanderSetReqMsg.getMajorCityId() != 0) {
                    respMsg.setRet(GameErrorCode.E_SUI_TANG_TWO_CITY_SET);
                    sendPacket(ClientProtocol.U_SUI_TANG_COMMANDER_SET, respMsg, userId);
                    return;
                }
                if (commanderSetReqMsg.hasMinorCityId() && commanderSetReqMsg.getMinorCityId() != 0) {
                    respMsg.setRet(GameErrorCode.E_SUI_TANG_TWO_CITY_SET);
                    sendPacket(ClientProtocol.U_SUI_TANG_COMMANDER_SET, respMsg, userId);
                    return;
                }
            }
            boolean isRepeat = false;
            if (commanderSetReqMsg.hasMajorCityId()) {
                if (commanderSetReqMsg.hasMinorCityId()) {
                    isRepeat = commanderSetReqMsg.getMajorCityId() == commanderSetReqMsg.getMinorCityId() && commanderSetReqMsg.getMajorCityId() != 0;
                } else {
                    isRepeat = commanderSetReqMsg.getMajorCityId() == commanderData.getMinorCityId() && commanderSetReqMsg.getMajorCityId() != 0;
                }
            }
            if (commanderSetReqMsg.hasMinorCityId()) {
                if (commanderSetReqMsg.hasMajorCityId()) {
                    isRepeat = commanderSetReqMsg.getMajorCityId() == commanderSetReqMsg.getMinorCityId() && commanderSetReqMsg.getMinorCityId() != 0;
                } else {
                    isRepeat = commanderData.getMajorCityId() == commanderSetReqMsg.getMinorCityId() && commanderSetReqMsg.getMinorCityId() != 0;
                }
            }
            if (isRepeat) {
                respMsg.setRet(GameErrorCode.E_SUI_TANG_REPEAT_CITY_SET);
                sendPacket(ClientProtocol.U_SUI_TANG_COMMANDER_SET, respMsg, userId);
                return;
            }

            // 设置信息
            boolean isNeedSync = false;
            if (commanderSetReqMsg.hasNotice()) {
                commanderData.setNotice(commanderSetReqMsg.getNotice());
                isNeedSync = true;
            }
            if (commanderSetReqMsg.hasMajorCityId()) {
                commanderData.setMajorCityId(commanderSetReqMsg.getMajorCityId());
                isNeedSync = true;
            }
            if (commanderSetReqMsg.hasMinorCityId()) {
                commanderData.setMinorCityId(commanderSetReqMsg.getMinorCityId());
                isNeedSync = true;
            }
            sendPacket(ClientProtocol.U_SUI_TANG_COMMANDER_SET, respMsg, userId);
            if (isNeedSync) {
                unionData.setCommanders(commanderData);
                // 同步信息给阵营玩家
                syncActivityMgr.syncCommanderInfoToUnion(userData.getUnionUid());
            }
            logActivityMgr.addCommandLog(userId, userData.getUnionUid());
        }
    }

    /*
     * 生成布告
     */
    private CrossSuiTangUnionBuGaoData oneBuGao(String unionUid, long userId, int goodId) {
        Map<Long, CrossSuiTangUnionBuGaoData> buGaoDataMap = buGaoMap.get(unionUid);
        if (buGaoDataMap == null) {
            buGaoDataMap = new ConcurrentHashMap<>();
            buGaoMap.put(unionUid, buGaoDataMap);
        }

        CrossSuiTangUnionBuGaoData buGaoData;
        synchronized (lock) {
            // 生成红包
            CrossSuiTangUnionRound unionRoundData = unionActivityMgr.getUnionRoundData(unionUid);
            buGaoData = new CrossSuiTangUnionBuGaoData();
            buGaoData.setActivityId(config.getActivityId());
            buGaoData.setGroupId(groupId);
            buGaoData.setActGroupId(unionRoundData.getActGroupId());
            buGaoData.setWarType(unionRoundData.getWarType());
            buGaoData.setRound(unionRoundData.getRound());
            buGaoData.setUserId(userId);
            buGaoData.setGoodId(goodId);
            buGaoData.setTime(System.currentTimeMillis());
            buGaoData.setBuGaoNo(buGaoDataMap.size() + 1);
            buGaoData.setUnionUid(unionUid);
            // 加map
            buGaoDataMap.put(buGaoData.getBuGaoNo(), buGaoData);
            buGaoData.setInsertOption();
            // 加统计数量
            addUserBuGaoCount(buGaoData);
        }

        return buGaoData;
    }

    /**
     * 使用道具后给阵营加安民布告
     */
    public void addBuGao(long userId, SuiTang.CrossSuiTangRedPacketAddReqMsg reqMsg) {
        if (!isAble(userId)) {
            logger.error("sui tang addRedPacket fail, no able! activityId {}, userId {}.", config.getActivityInfo().getActivityId(), userId);
            return;
        }
        CrossSuiTangUserData userData = getUserData(userId);
        String unionUid = userData.getUnionUid();
        CrossSuiTangUnionData unionData = unionDataMap.get(unionUid);
        if (unionData == null) {
            logger.error("sui tang addRedPacket fail, no camp data! activityId {}, userId {}.", config.getActivityInfo().getActivityId(), userId);
            return;
        }

        List<CrossSuiTangUnionBuGaoData> buGaoSyncList = new ArrayList<>();
        synchronized (lock) {
            for (int i = 0; i < reqMsg.getNum(); i++) {
                buGaoSyncList.add(oneBuGao(unionUid, userId, reqMsg.getGoodId()));
            }
        }

        getBuGaoList(userId);
        // 红点
        if (!unionUid.isEmpty()) {
            syncActivityMgr.addRedDotToAll(new ArrayList<>(syncActivityMgr.getUnionJoin(unionUid).getMemberMap().keySet()), eSuiTangRedDotType.Type1_BuGaoCanGet);
        }
    }

    /*
     * 新增玩家的安民布告信息
     */
    public void addUserBuGaoCount(CrossSuiTangUnionBuGaoData buGaoData) {
        if (!userBuGaoMap.containsKey(buGaoData.getUserId())) {
            CrossSuiTangUserBuGaoCount temp = new CrossSuiTangUserBuGaoCount();
            temp.setUserId(buGaoData.getUserId());
            userBuGaoMap.put(buGaoData.getUserId(), temp);
        }
        CrossSuiTangUserBuGaoCount userRedPacket = userBuGaoMap.get(buGaoData.getUserId());
        Map<Integer, Integer> buGaoCountMap = userRedPacket.getUserRedPacketCountMap();
        buGaoCountMap.put(buGaoData.getGoodId(), buGaoCountMap.getOrDefault(buGaoData.getGoodId(), 0) + 1);
        userRedPacket.setUserRedPacketCountMap(buGaoCountMap);
    }

    /*
     * 增加安民布告领取信息
     */
    public void addUserBuGaoCountForGet(CrossSuiTangUnionBuGaoData buGaoData, long userId) {
        CrossSuiTangUserBuGaoCount userBuGaoCount = userBuGaoForGetMap.get(userId);
        if (userBuGaoCount == null) {
            userBuGaoCount = new CrossSuiTangUserBuGaoCount();
            userBuGaoCount.setUserId(userId);
            userBuGaoForGetMap.put(userId, userBuGaoCount);
        }
        Map<Integer, Integer> userBuGaoCountMap = userBuGaoCount.getUserRedPacketCountMap();
        userBuGaoCountMap.put(buGaoData.getGoodId(), userBuGaoCountMap.getOrDefault(buGaoData.getGoodId(), 0) + 1);
        userBuGaoCount.setUserRedPacketCountMap(userBuGaoCountMap);
    }

    /*
     * 增加民心（成就领取后）
     */
    public void addMinXin(long userId, SuiTang.CrossSuiTangAddMinXinReqMsg reqMsg) {
        SuiTang.CrossSuiTangRedPacketGetBoxRespMsg.Builder serverMsg = SuiTang.CrossSuiTangRedPacketGetBoxRespMsg.newBuilder();
        serverMsg.setRet(0);

        // 资格
        if (!isAble(userId)) {
            serverMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(GameProtocol.S_CROSS_SUI_TANG_BU_GAO_GET_BOX, serverMsg, userId);
            return;
        }

        // 数据判断
        CrossSuiTangUserData userData = getUserData(userId);
        CrossSuiTangUnionData unionData = unionDataMap.get(userData.getUnionUid());
        if (unionData == null) {
            serverMsg.setRet(GameErrorCode.E_SUI_TANG_RED_PACKET_IS_GET);
            sendPacket(GameProtocol.S_CROSS_SUI_TANG_BU_GAO_GET_BOX, serverMsg, userId);
            return;
        }
        unionData.setRedPacketValue(unionData.getRedPacketValue() + reqMsg.getNum());
        syncActivityMgr.syncRedPacketBoxValue(unionData.getUnionUid());
        logActivityMgr.addMinXinLog(unionData.getUnionUid(), reqMsg.getNum());
    }

    /**
     * 领取安民布告
     */
    public void getBuGaoBox(long userId, SuiTang.CrossSuiTangRedPacketGetBoxReqMsg reqMsg) {
        SuiTang.CrossSuiTangRedPacketGetBoxRespMsg.Builder serverMsg = SuiTang.CrossSuiTangRedPacketGetBoxRespMsg.newBuilder();
        serverMsg.setRet(0);

        // 资格
        if (!isAble(userId)) {
            serverMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(GameProtocol.S_CROSS_SUI_TANG_BU_GAO_GET_BOX, serverMsg, userId);
            return;
        }

        // 数据判断
        CrossSuiTangUserData userData = getUserData(userId);
        CrossSuiTangUnionData unionData = unionDataMap.get(userData.getUnionUid());
        if (unionData == null) {
            serverMsg.setRet(GameErrorCode.E_SUI_TANG_RED_PACKET_IS_GET);
            sendPacket(GameProtocol.S_CROSS_SUI_TANG_BU_GAO_GET_BOX, serverMsg, userId);
            return;
        }

        long boxNo = StringUtils.isNullOrEmpty(reqMsg.getOrderNo()) ? 0 : Long.valueOf(reqMsg.getOrderNo());
        Map<Integer, SuiTangCampBoxConfig> campBoxConfigMap = config.getCampBoxConfigMap();

        synchronized (lock) {

            if (boxNo == 0) {
                // 【一键领取】
                Property reward = new Property();
                long minXin = 0;
                for (CrossSuiTangUnionBuGaoData buGaoData : buGaoMap.get(unionData.getUnionUid()).values()) {
                    Set<Long> getRewardUserList = buGaoData.getGetRewardUserList();
                    if (!getRewardUserList.contains(userId)) {
                        SuiTangCampBoxConfig campBoxConfig = campBoxConfigMap.get(buGaoData.getGoodId());
                        reward.addProperty(campBoxConfig.getBoxId(), BigInteger.ONE);
                        getRewardUserList.add(userId);
                        buGaoData.setUpdateOption();
                        unionData.setRedPacketValue(unionData.getRedPacketValue() + campBoxConfig.getBoxScore());
                        minXin += campBoxConfig.getBoxScore();
                        addUserBuGaoCountForGet(buGaoData, userId);
                    }
                }
                String rewardStr = PropertyHelper.parsePropertyToString(reward);
                if (StringUtils.isNullOrEmpty(rewardStr)) {
                    serverMsg.setRet(GameErrorCode.E_SUI_TANG_RED_PACKET_IS_GET);
                    sendPacket(GameProtocol.S_CROSS_SUI_TANG_BU_GAO_GET_BOX, serverMsg, userId);
                    return;
                }
                serverMsg.setReward(rewardStr);
                serverMsg.setMinXin(minXin);
                sendPacket(GameProtocol.S_CROSS_SUI_TANG_BU_GAO_GET_BOX, serverMsg, userId);
                unionData.setUpdateOption();
                logActivityMgr.addMinXinLog(unionData.getUnionUid(), minXin);
            } else {
                // 【单个领取】
                CrossSuiTangUnionBuGaoData buGaoData = buGaoMap.get(unionData.getUnionUid()).get(boxNo);
                if (buGaoData == null) {
                    serverMsg.setRet(GameErrorCode.E_SUI_TANG_RED_PACKET_NO_EXIT);
                    sendPacket(GameProtocol.S_CROSS_SUI_TANG_BU_GAO_GET_BOX, serverMsg, userId);
                    return;
                }
                Set<Long> getRewardList = buGaoData.getGetRewardUserList();
                if (getRewardList.contains(userId)) {
                    serverMsg.setRet(GameErrorCode.E_SUI_TANG_RED_PACKET_IS_GET);
                    sendPacket(GameProtocol.S_CROSS_SUI_TANG_BU_GAO_GET_BOX, serverMsg, userId);
                    return;
                }
                SuiTangCampBoxConfig campBoxConfig = campBoxConfigMap.get(buGaoData.getGoodId());
                getRewardList.add(userId);
                buGaoData.setUpdateOption();
                unionData.setRedPacketValue(unionData.getRedPacketValue() + campBoxConfig.getBoxScore());
                serverMsg.setReward(campBoxConfig.getBoxId() + "=1");
                // 一键领取的时候还要下去连大宝箱都领了
                serverMsg.setBoxValue(unionData.getRedPacketValue());
                serverMsg.setActivityId(config.getActivityInfo().getActivityId());
                serverMsg.setMinXin(campBoxConfig.getBoxScore());
                addUserBuGaoCountForGet(buGaoData, userId);
                sendPacket(GameProtocol.S_CROSS_SUI_TANG_BU_GAO_GET_BOX, serverMsg, userId);
                unionData.setUpdateOption();
                logActivityMgr.addMinXinLog(unionData.getUnionUid(), campBoxConfig.getBoxScore());
            }

        }
        syncActivityMgr.readRedDotByCmd(userId, eSuiTangRedDotType.Type1_BuGaoCanGet.getValue());
        syncActivityMgr.syncRedPacketBoxValue(unionData.getUnionUid());
    }

    /**
     * 初始化安民布告信息统计数据
     */
    public void initUserBuGaoNumMap() {
        for (Map<Long, CrossSuiTangUnionBuGaoData> buGaoDataMap : buGaoMap.values()) {
            for (CrossSuiTangUnionBuGaoData buGaoData : buGaoDataMap.values()) {
                if (!userBuGaoMap.containsKey(buGaoData.getUserId())) {
                    CrossSuiTangUserBuGaoCount temp = new CrossSuiTangUserBuGaoCount();
                    temp.setUserId(buGaoData.getUserId());
                    userBuGaoMap.put(buGaoData.getUserId(), temp);
                }
                CrossSuiTangUserBuGaoCount userRedPacketCount = userBuGaoMap.get(buGaoData.getUserId());
                Map<Integer, Integer> redPacketCountMap = userRedPacketCount.getUserRedPacketCountMap();
                redPacketCountMap.put(buGaoData.getGoodId(), redPacketCountMap.getOrDefault(buGaoData.getGoodId(), 0) + 1);
                userRedPacketCount.setUserRedPacketCountMap(redPacketCountMap);
                // 布告领取记录统计
                if (!userBuGaoForGetMap.containsKey(buGaoData.getUserId())) {
                    CrossSuiTangUserBuGaoCount temp = new CrossSuiTangUserBuGaoCount();
                    temp.setUserId(buGaoData.getUserId());
                    userBuGaoForGetMap.put(buGaoData.getUserId(), temp);
                }
                for (Long userId : buGaoData.getGetRewardUserList()) {
                    CrossSuiTangUserBuGaoCount userBuGaoCount = userBuGaoForGetMap.get(userId);
                    if (userBuGaoCount == null) {
                        userBuGaoCount = new CrossSuiTangUserBuGaoCount();
                        userBuGaoCount.setUserId(userId);
                        userBuGaoForGetMap.put(userId, userBuGaoCount);
                    }
                    Map<Integer, Integer> userBuGaoCountMap = userBuGaoCount.getUserRedPacketCountMap();
                    userBuGaoCountMap.put(buGaoData.getGoodId(), userBuGaoCountMap.getOrDefault(buGaoData.getGoodId(), 0) + 1);
                    userBuGaoCount.setUserRedPacketCountMap(userBuGaoCountMap);
                }
            }
        }
    }

    /*
     * 获取同阵营商会玩家数据
     */
    public void getUnionUserDataCmd(long userId) {
        SuiTang.SuiTangUnionUserDataRespMsg.Builder builder = SuiTang.SuiTangUnionUserDataRespMsg.newBuilder();
        builder.setRet(0);
        if (!isAble(userId)) {
            builder.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_UNION_USER_DATA, builder, userId);
            return;
        }
        CrossSuiTangUserData userData = getUserData(userId);
        CrossSuiTangUnionJoinData unionJoinData = getUnionJoinDataMap().get(userData.getUnionUid());
        for (CrossSuiTangUnionJoinMember member : unionJoinData.getMemberMap().values()) {
            CrossSuiTangUserData userDataMember = getUserData(member.getUserId());
            SuiTang.SuiTangUnionUserDataTemp.Builder builderZG = SuiTang.SuiTangUnionUserDataTemp.newBuilder();
            builderZG.setUserId(member.getUserId());
            builderZG.setZhanGong(userDataMember.getZhanGong());
            builder.addUnionUserList(builderZG);
        }
        sendPacket(ClientProtocol.U_SUI_TANG_UNION_USER_DATA, builder, userId);
    }

    /**
     * 安民布告发送记录
     */
    public void getBuGaoRecord(long userId) {
        SuiTang.SuiTangBuGaoGetRecordRespMsg.Builder respMsg = SuiTang.SuiTangBuGaoGetRecordRespMsg.newBuilder();
        respMsg.setRet(0);

        if (!isAble(userId)) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_BU_GAO_RECORD_LIST, respMsg, userId);
            return;
        }

        CrossSuiTangUserData userData = getUserData(userId);
        if (userData == null) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_BU_GAO_RECORD_LIST, respMsg, userId);
            return;
        }
        String unionUid = userData.getUnionUid();
        if (unionUid == null || unionUid.isEmpty()) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_BU_GAO_RECORD_LIST, respMsg, userId);
            return;
        }

        for (CrossSuiTangUserBuGaoCount userRedPacket : userBuGaoMap.values()) {
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userRedPacket.getUserId());
            if (userBaseInfo == null) {
                userBaseInfo = new UserBaseInfo();
            }
            if (!Objects.equals(getUserData(userRedPacket.getUserId()).getUnionUid(), unionUid)) {
                continue;
            }

            SuiTang.SuiTangBuGaoRankMsg.Builder rankTempMsg = SuiTang.SuiTangBuGaoRankMsg.newBuilder();
            rankTempMsg.setUserId(userRedPacket.getUserId());
            rankTempMsg.setNickName(userBaseInfo.getNickName());
            for (Map.Entry<Integer, Integer> entry : userRedPacket.getUserRedPacketCountMap().entrySet()) {
                SuiTang.SuiTangBuGaoBoxMsg.Builder boxTempMsg = SuiTang.SuiTangBuGaoBoxMsg.newBuilder();
                boxTempMsg.setBoxKey(entry.getKey());
                boxTempMsg.setNum(entry.getValue());
                rankTempMsg.addBox(boxTempMsg);
            }
            respMsg.addRecords(rankTempMsg);
        }

        sendPacket(ClientProtocol.U_SUI_TANG_BU_GAO_RECORD_LIST, respMsg, userId);
    }

    /**
     * 安民布告领取记录
     */
    public void getBuGaoRecordForGet(long userId) {
        SuiTang.SuiTangBuGaoGetRecordForGetRespMsg.Builder respMsg = SuiTang.SuiTangBuGaoGetRecordForGetRespMsg.newBuilder();
        respMsg.setRet(0);

        if (!isAble(userId)) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_BU_GAO_RECORD_LIST_FOR_GET, respMsg, userId);
            return;
        }

        CrossSuiTangUserData userData = getUserData(userId);
        if (userData == null) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_BU_GAO_RECORD_LIST_FOR_GET, respMsg, userId);
            return;
        }
        String unionUid = userData.getUnionUid();
        if (unionUid == null || unionUid.isEmpty()) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_BU_GAO_RECORD_LIST_FOR_GET, respMsg, userId);
            return;
        }

        for (CrossSuiTangUserBuGaoCount userRedPacket : userBuGaoForGetMap.values()) {
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userRedPacket.getUserId());
            if (userBaseInfo == null) {
                userBaseInfo = new UserBaseInfo();
            }

            if (!Objects.equals(getUserData(userRedPacket.getUserId()).getUnionUid(), unionUid)) {
                continue;
            }

            SuiTang.SuiTangBuGaoRankMsg.Builder rankTempMsg = SuiTang.SuiTangBuGaoRankMsg.newBuilder();
            rankTempMsg.setUserId(userRedPacket.getUserId());
            rankTempMsg.setNickName(userBaseInfo.getNickName());
            for (Map.Entry<Integer, Integer> entry : userRedPacket.getUserRedPacketCountMap().entrySet()) {
                SuiTang.SuiTangBuGaoBoxMsg.Builder boxTempMsg = SuiTang.SuiTangBuGaoBoxMsg.newBuilder();
                boxTempMsg.setBoxKey(entry.getKey());
                boxTempMsg.setNum(entry.getValue());
                rankTempMsg.addBox(boxTempMsg);
            }
            respMsg.addRecords(rankTempMsg);
        }

        sendPacket(ClientProtocol.U_SUI_TANG_BU_GAO_RECORD_LIST_FOR_GET, respMsg, userId);
    }

    /**
     * 获取红包列表（优先没领取的）
     */
    public void getBuGaoList(long userId) {
        SuiTang.SuiTangBuGaoGetListRespMsg.Builder respMsg = SuiTang.SuiTangBuGaoGetListRespMsg.newBuilder();
        respMsg.setRet(0);

        // 没资格
        if (!isAble(userId)) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_BU_GAO_LIST, respMsg, userId);
            return;
        }

        // 统计红包
        CrossSuiTangUserData userData = getUserData(userId);
        String unionUid = userData.getUnionUid();
        LinkedList<CrossSuiTangUnionBuGaoData> noGetRewardList = new LinkedList<>();
        LinkedList<CrossSuiTangUnionBuGaoData> getRewardList = new LinkedList<>();
        if (buGaoMap.isEmpty() || !buGaoMap.containsKey(unionUid)) {
            sendPacket(ClientProtocol.U_SUI_TANG_BU_GAO_LIST, respMsg, userId);
            return;
        }
        for (CrossSuiTangUnionBuGaoData redPacket : buGaoMap.get(unionUid).values()) {
            if (redPacket.getGetRewardUserList().contains(userId)) {
                getRewardList.add(redPacket);
            } else {
                noGetRewardList.add(redPacket);
            }
        }

        // 发送晚的在前
        noGetRewardList.sort(new CrossSuiTangActivity.RedPacketSort());
        getRewardList.sort(new CrossSuiTangActivity.RedPacketSort());

        // 拿前50个
        int maxNum = 100;
        int num = 1;
        for (CrossSuiTangUnionBuGaoData buGaoData : noGetRewardList) {
            if (num >= maxNum) {
                break;
            }
            respMsg.addRedPackets(parseSuiTangUnionBuGaoMsg(buGaoData, false));
            num++;
        }
        for (CrossSuiTangUnionBuGaoData redPacket : getRewardList) {
            if (num >= maxNum) {
                break;
            }
            respMsg.addRedPackets(parseSuiTangUnionBuGaoMsg(redPacket, true));
            num++;
        }

        sendPacket(ClientProtocol.U_SUI_TANG_BU_GAO_LIST, respMsg, userId);
    }

    public void updateUserMuBing(long userId, long remainMuBinNum) {
        CrossSuiTangUserData userData = userDataMap.get(userId);
        if (userData == null) {
            return;
        }
        CrossSuiTangBarracks barracks = userData.getBarracks();
        if (barracks == null) {
            return;
        }

        barracks.setRemainMuBing(remainMuBinNum);

        userData.setUpdateOption();
    }

    public SuiTang.SuiTangGetMemberSoldierRespMsg.Builder getMemberSoldier(long userId) {
        SuiTang.SuiTangGetMemberSoldierRespMsg.Builder builder = SuiTang.SuiTangGetMemberSoldierRespMsg.newBuilder();
        builder.setRet(0);
        CrossSuiTangUserData userData = userDataMap.get(userId);
        if (userData == null) {
            return builder;
        }

        CrossSuiTangUnionJoinData unionJoinData = unionJoinDataMap.get(userData.getUnionUid());
        if (unionJoinData == null) {
            return builder;
        }

        for (CrossSuiTangUnionJoinMember member : unionJoinData.getMemberMap().values()) {
            CrossSuiTangUserData memberUserData = userDataMap.get(member.getUserId());
            if (memberUserData == null) {
                continue;
            }

            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(member.getUserId());
            if (userBaseInfo == null) {
                continue;
            }

            CrossSuiTangBarracks barracks = memberUserData.getBarracks();
            if (barracks == null) {
                continue;
            }

            barracksActivityMgr.barracksCalc(member.getUserId());

            long soldierNum = barracks.getReadyNum() + barracks.getRemainMuBing();
            SuiTang.SuiTangMemberSoldierTemp.Builder memberBuilder = SuiTang.SuiTangMemberSoldierTemp.newBuilder();
            memberBuilder.setUserId(member.getUserId());
            memberBuilder.setSoldierNum(soldierNum);
            memberBuilder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));

            builder.addList(memberBuilder);
        }

        return builder;
    }

    public String getUserAreaParam(long userId) {
        CrossSuiTangUserData userData = userDataMap.get(userId);
        if (userData == null) {
            return null;
        }
        CrossSuiTangUnionData unionData = unionDataMap.get(userData.getUnionUid());
        if (unionData == null) {
            return null;
        }

        CrossSuiTangUserRound curUserRound = cityActivityMgr.getCurUserRound(userId);
        if (curUserRound == null) {
            return null;
        }

        JSONObject json = new JSONObject();
        json.put("area", curUserRound.getWarType().getType());
        json.put("group", curUserRound.getActGroupId() + 1);
        return json.toJSONString();
    }

    class RedPacketSort implements Comparator<CrossSuiTangUnionBuGaoData> {
        @Override
        public int compare(CrossSuiTangUnionBuGaoData o1, CrossSuiTangUnionBuGaoData o2) {
            return Long.compare(o2.getTime(), o1.getTime());
        }
    }

    /*
     * setAutoMoveByCmd
     */
    public void setAutoMoveByCmd(long userId, boolean isAuto) {
        if (!this.isBattleStep()) {
            SuiTang.SuiTangSetAutoMoveTeamRespMsg.Builder builder = SuiTang.SuiTangSetAutoMoveTeamRespMsg.newBuilder();
            builder.setRet(GameErrorCode.E_SUI_TANG_NO_OPERATE_TIME);
            sendPacket(ClientProtocol.U_SUI_TANG_SET_AUTO_MOVE_TEAM, builder, userId);
            return;
        }

        CrossSuiTangUserData userData = getUserData(userId);
        if (userData == null) {
            SuiTang.SuiTangSetAutoMoveTeamRespMsg.Builder builder = SuiTang.SuiTangSetAutoMoveTeamRespMsg.newBuilder();
            builder.setRet(GameErrorCode.E_SUI_TANG_PARAM_ERR);
            sendPacket(ClientProtocol.U_SUI_TANG_SET_AUTO_MOVE_TEAM, builder, userId);
            return;
        }
        userData.getTeam().setAutoMove(isAuto);
//        if (isAuto) {
//            userData.getTeam().setAutoBattle(isAuto);
//        } else {
//            userData.getTeam().setTargetCityId(0);
//        }
        // 可以的话，开始自动行军
//        if (userData.getTeam() != null && userData.getTeam().getTargetCityId() != 0) {
//            mapActivityMgr.autoMoveToCity(userData.getTeam(), userData.getTeam().getTargetCityId());
//        }
        SuiTang.SuiTangSetAutoMoveTeamRespMsg.Builder builder = SuiTang.SuiTangSetAutoMoveTeamRespMsg.newBuilder();
        builder.setRet(0);
        builder.setIsAuto(isAuto);
        sendPacket(ClientProtocol.U_SUI_TANG_SET_AUTO_MOVE_TEAM, builder, userId);
        syncActivityMgr.syncTeamToSelf(userData.getTeam());
    }

    public void setAutoAttackByCmd(long userId, boolean isAuto) {
        if (!this.isBattleStep()) {
            SuiTang.SuiTangSetAutoBattleRespMsg.Builder builder = SuiTang.SuiTangSetAutoBattleRespMsg.newBuilder();
            builder.setRet(GameErrorCode.E_SUI_TANG_NO_OPERATE_TIME);
            sendPacket(ClientProtocol.U_SUI_TANG_SET_AUTO_BATTLE, builder, userId);
            return;
        }

        CrossSuiTangUserData userData = getUserData(userId);
        if (userData == null) {
            SuiTang.SuiTangSetAutoBattleRespMsg.Builder builder = SuiTang.SuiTangSetAutoBattleRespMsg.newBuilder();
            builder.setRet(GameErrorCode.E_SUI_TANG_PARAM_ERR);
            sendPacket(ClientProtocol.U_SUI_TANG_SET_AUTO_BATTLE, builder, userId);
            return;
        }
        userData.getTeam().setAutoBattle(isAuto);
        CrossSuiTangCity city = cityActivityMgr.getCity(userId);
        CrossSuiTangBattlefieldTeam battleTeam = battleActivityMgr.getBattleTeam(city, userId);
        if (city == null || battleTeam == null) {
            SuiTang.SuiTangSetAutoBattleRespMsg.Builder builder = SuiTang.SuiTangSetAutoBattleRespMsg.newBuilder();
            builder.setRet(GameErrorCode.E_SUI_TANG_PARAM_ERR);
            sendPacket(ClientProtocol.U_SUI_TANG_SET_AUTO_BATTLE, builder, userId);
            return;
        }
        // 自动战斗
        if (isAuto) {
            battleActivityMgr.autoAttack(city, battleTeam);
        }
        SuiTang.SuiTangSetAutoBattleRespMsg.Builder builder = SuiTang.SuiTangSetAutoBattleRespMsg.newBuilder();
        builder.setRet(0);
        builder.setIsAuto(isAuto);
        sendPacket(ClientProtocol.U_SUI_TANG_SET_AUTO_BATTLE, builder, userId);
    }

    /**
     * 城池采集界面信息
     */
    public void cityFoodInfo(long userId) {
        if (!isAble(userId)) {
            // 没资格的不可能打开采集界面
            return;
        }

        // 协议
        CrossSuiTangUserData userData = getUserData(userId);
        SuiTang.SuiTangCityFoodRespMsg.Builder respMsg = SuiTang.SuiTangCityFoodRespMsg.newBuilder();
        respMsg.setRet(0);

        String unionUid = userData.getUnionUid();
        CrossSuiTangUserRound curUserRound = cityActivityMgr.getCurUserRound(userId);
        if (curUserRound == null) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_PARAM_ERR);
            sendPacket(ClientProtocol.U_SUI_TANG_CITY_FOOD, respMsg, userId);
            return;
        }

        long time = System.currentTimeMillis();
        if (config.getSuiTangStage().getValue() >= eSuiTangStage.Stage1EndTime.getValue() || config.getSuiTangStage().getValue() == eSuiTangStage.Stage1RestTime.getValue()) {
            sendPacket(ClientProtocol.U_SUI_TANG_CITY_FOOD, respMsg, userId);
            return;
        } else {
            time = Math.min(time, DateHelper.getTodayZeroTimeStamp() + 22 * DateHelper.HOUR_MILLIONS);
        }

        // 重新计算采集
        cityActivityMgr.makeAllCityCollect(unionUid, time, calcRound());

        Set<Integer> hadCitySet = new HashSet<>();

        CrossSuiTangUnionData unionData = unionDataMap.get(unionUid);
        if (unionData != null) {
            // 有收益的城池
            Map<Integer, CrossSuiTangCollect> cityValueMap = unionData.getCollectionMap().getOrDefault(userId, new ConcurrentHashMap<>());
            for (Map.Entry<Integer, CrossSuiTangCollect> entry : cityValueMap.entrySet()) {
                int cityId = entry.getKey();
                CrossSuiTangCollect value = entry.getValue();

                if (value.getJunZi() <= 0 && value.getMuBingLing() <= 0) {
                    continue; // 没收益
                }

                SuiTang.SuiTangCityFoodMsg.Builder tempMsg = SuiTang.SuiTangCityFoodMsg.newBuilder();
                tempMsg.setCityId(cityId);
                tempMsg.setFood(value.getJunZi());
                tempMsg.setMuBingLing(value.getMuBingLing());
                tempMsg.setMuBingLingProduction(cityActivityMgr.getCityFoodProductBuffPer(curUserRound.getWarType(), curUserRound.getActGroupId(), cityId, calcRound(), unionUid, eSuiTangBuffType.Type2_CityMuBingLing));
                tempMsg.setFoodProduction(cityActivityMgr.getCityFoodProductBuffPer(curUserRound.getWarType(), curUserRound.getActGroupId(), cityId, calcRound(), unionUid, eSuiTangBuffType.Type8_CityFoodProduce)); // 产出速度
                respMsg.addFoods(tempMsg);

                hadCitySet.add(cityId);
            }
        }

        // 无收益但占领的城池
        for (CrossSuiTangCity city : cityActivityMgr.getCurCityMap(userId).values()) {
            if (hadCitySet.contains(city.getCityId()) || !Objects.equals(city.getUnionId(), unionUid)) {
                continue;
            }
            SuiTang.SuiTangCityFoodMsg.Builder tempMsg = SuiTang.SuiTangCityFoodMsg.newBuilder();
            tempMsg.setCityId(city.getCityId());
            tempMsg.setFood(0);
            tempMsg.setMuBingLing(0);
            tempMsg.setMuBingLingProduction(cityActivityMgr.getCityFoodProductBuffPer(curUserRound.getWarType(), curUserRound.getActGroupId(), city.getCityId(), calcRound(), unionUid, eSuiTangBuffType.Type2_CityMuBingLing));
            tempMsg.setFoodProduction(cityActivityMgr.getCityFoodProductBuffPer(curUserRound.getWarType(), curUserRound.getActGroupId(), city.getCityId(), calcRound(), unionUid, eSuiTangBuffType.Type8_CityFoodProduce));
            respMsg.addFoods(tempMsg);
        }

        sendPacket(ClientProtocol.U_SUI_TANG_CITY_FOOD, respMsg, userId);
    }

    /*
     * 城池一键采集
     */
    public void cityFoodCollect(long userId) {
        SuiTang.CrossSuiTangCityFoodCollectRespMsg.Builder builder = SuiTang.CrossSuiTangCityFoodCollectRespMsg.newBuilder();
        builder.setRet(0);

        if (!isAble(userId)) {
            builder.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_CITY_FOOD_COLLECT, builder, userId);
            return;
        }
        if (config.getSuiTangStage().getValue() >= eSuiTangStage.Stage1EndTime.getValue() || config.getSuiTangStage().getValue() == eSuiTangStage.Stage1RestTime.getValue()) {
            builder.setRet(GameErrorCode.E_SUI_TANG_NO_OPERATE_TIME);
            sendPacket(ClientProtocol.U_SUI_TANG_CITY_FOOD_COLLECT, builder, userId);
            return;
        }

        CrossSuiTangUserData userData = getUserData(userId);
        cityActivityMgr.makeAllCityCollect(userData.getUnionUid(), System.currentTimeMillis(), calcRound());

        // 统计总奖励
        long userAllValue = 0L;
        long userMuBingLing = 0L;
        CrossSuiTangUnionData unionData = unionDataMap.get(userData.getUnionUid());
        if (unionData != null) {
            synchronized (lock) {
                Map<Long, Map<Integer, CrossSuiTangCollect>> collectionMap = unionData.getCollectionMap();
                Map<Integer, CrossSuiTangCollect> cityValueMap = collectionMap.getOrDefault(userId, new ConcurrentHashMap<>());
                for (Map.Entry<Integer, CrossSuiTangCollect> entry : cityValueMap.entrySet()) {
                    Integer cityId = entry.getKey();
                    userAllValue += entry.getValue().getJunZi();
                    userMuBingLing += entry.getValue().getMuBingLing();
                    logActivityMgr.addJunZiLog(userId, cityId, entry.getValue().getJunZi());
                }
                collectionMap.put(userId, new ConcurrentHashMap<>()); // 清空
                unionData.setUpdateOption();
            }
        }

        if (userAllValue <= 0 && userMuBingLing <= 0) {
            // 没奖励
            builder.setRet(GameErrorCode.E_SUI_TANG_CITY_FOOD_COLLECT_NO_VALUE);
            sendPacket(ClientProtocol.U_SUI_TANG_CITY_FOOD_COLLECT, builder, userId);
            return;
        }
        String reward = "";
        if (userAllValue > 0) {
            reward = config.getParamConfig().getJunZiItem() + "=" + userAllValue;
        }
        if (userMuBingLing > 0) {
            if (reward.isEmpty()) {
                reward = config.getParamConfig().getMuBingLingItem() + "=" + userMuBingLing;
            } else {
                reward += ";" + config.getParamConfig().getMuBingLingItem() + "=" + userMuBingLing;
            }
        }
        builder.setReward(reward);
        sendPacket(GameProtocol.S_CROSS_SUI_TANG_CITY_FOOD_COLLECT, builder, userId);
    }

    /*
     * 进入活动请求
     */
    public void enterActivity(long userId) {
        SuiTang.SuiTangEnterActivityRespMsg.Builder builder = SuiTang.SuiTangEnterActivityRespMsg.newBuilder();
        for (CrossSuiTangUnionJoinData unionJoinData : unionJoinDataMap.values()) {
            builder.addUnionList(parseSuiTangUnionTempMsg(unionJoinData));
        }
        builder.setRet(0);
        sendPacket(ClientProtocol.U_SUI_TANG_ENTER_ACTIVITY, builder, userId);
    }

    /*
     * 获取城主（第一商会）的信息
     */
    public void getCityWinner(long userId) {
        SuiTang.SuiTangCityWinnerRespMsg.Builder builder = SuiTang.SuiTangCityWinnerRespMsg.newBuilder();
        int ret = 0;
        do {
            if (config.getSuiTangStage().getValue() < eSuiTangStage.Stage1EndTime.getValue()) {
                ret = GameErrorCode.E_SUI_TANG_NO_WINNER;
                break;
            }
            List<UnionYRank> sortUnionRankList = CrossYRankMgr.getSortUnionRankList(config.getActivityId(), groupId, String.valueOf(eGamePlayerEventType.SuiTangUnionScoreRank.getValue()));
            if (sortUnionRankList.isEmpty()) {
                ret = GameErrorCode.E_SUI_TANG_NO_WINNER;
                break;
            }
            UnionYRank unionYRank = sortUnionRankList.get(0);
            CrossSuiTangUnionJoinData unionJoinData = unionJoinDataMap.get(unionYRank.getUnionUid());
            builder.setUnion(parseSuiTangUnionTempMsg(unionJoinData));
            Map<Long, CrossSuiTangUnionJoinMember> memberMap = unionJoinData.getMemberMap();
            for (CrossSuiTangUnionJoinMember member : memberMap.values()) {
                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(member.getUserId());
                if (userBaseInfo == null) {
                    continue;
                }
                SuiTang.SuiTangUserPositionMsg.Builder builderMember = SuiTang.SuiTangUserPositionMsg.newBuilder();
                builderMember.setUserId(member.getUserId());
                builderMember.setPosition(member.getPosition());
                long zhangong = getUserData(member.getUserId()).getZhanGong();
                builderMember.setZhangong(zhangong);
                builderMember.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                builder.addList(builderMember);
            }
        } while (false);
        builder.setRet(ret);
        sendPacket(ClientProtocol.U_SUI_TANG_CITY_WINNER, builder, userId);
    }

    /*
     * 获取轮次分组信息
     */
    public void getGroupInfoCmd(long userId, SuiTang.SuiTangGroupReqMsg req) {
        SuiTang.SuiTangGroupRespMsg.Builder builder = SuiTang.SuiTangGroupRespMsg.newBuilder();
        CrossSuiTangUserRound user = groupActivityMgr.getCurUserRound(userId);
        int ret = 0;
        do {
            if (req == null) {
                ret = GameErrorCode.E_SUI_TANG_PARAM_ERR;
                break;
            }
            Map<Integer, CrossSuiTangRankListModel> listModelMap = warUnionRankMap.get(user.getWarType());
            if (listModelMap == null || listModelMap.isEmpty()) {
                ret = GameErrorCode.E_SUI_TANG_PARAM_ERR;
                break;
            }
            CrossSuiTangRankListModel groupListModel = listModelMap.get(user.getActGroupId());
            if (groupListModel == null) {
                ret = GameErrorCode.E_SUI_TANG_PARAM_ERR;
                break;
            }
            CrossSuiTangRank myRankInfo = groupListModel.getMyRankInfo(getUserData(userId).getUnionUid());
            if (myRankInfo == null) {
                ret = GameErrorCode.E_SUI_TANG_PARAM_ERR;
                break;
            }
            builder.setMyRank(groupListModel.getMyRank(getUserData(userId).getUnionUid()));
            builder.setMyCityScore((int) myRankInfo.getValue());
            Map<eSuiTangWarType, Map<Integer, CrossSuiTangGroup>> warTypeMap = crossSuiTangData.getActGroupMap().get(calcRound());
            if (warTypeMap == null || warTypeMap.isEmpty()) {
                ret = GameErrorCode.E_SUI_TANG_PARAM_ERR;
                break;
            }
            if (req.getNeedUnion()) {
                for (Map<Integer, CrossSuiTangRankListModel> groupListModelMap : warUnionRankMap.values()) {
                    if (groupListModelMap == null || groupListModelMap.isEmpty()) {
                        continue;
                    }
                    for (CrossSuiTangRankListModel listModel : groupListModelMap.values()) {
                        for (CrossSuiTangRank rank : listModel.getRankList()) {
                            CrossSuiTangUnionRound unionRoundData = unionActivityMgr.getUnionRoundData(rank.getId());
                            if (unionRoundData == null) {
                                continue;
                            }
                            if (unionRoundData.getWarType() == eSuiTangWarType.WAR_TYPE_YIJUN) {
                                builder.addYiJunUnionRankList(parseSuiTangUnionMsg(unionRoundData));
                            }
                            if (unionRoundData.getWarType() == eSuiTangWarType.WAR_TYPE_XIAOQI) {
                                builder.addXiaoQiUnionRankList(parseSuiTangUnionMsg(unionRoundData));
                            }
                            if (unionRoundData.getWarType() == eSuiTangWarType.WAR_TYPE_JINJUN) {
                                builder.addJinJunUnionRankList(parseSuiTangUnionMsg(unionRoundData));
                            }
                        }
                    }
                }
            }
        } while (false);

        builder.setRet(ret);
        sendPacket(ClientProtocol.U_SUI_TANG_ROUND_GROUP, builder, userId);
    }

    /*
     * 请求城池列表信息
     */
    public void cityInfoCmd(long userId, SuiTang.SuiTangCityInfoReqMsg reqMsg) {
        SuiTang.SuiTangCityInfoRespMsg.Builder builder = SuiTang.SuiTangCityInfoRespMsg.newBuilder();
        builder.setRet(0);
        if (reqMsg == null || reqMsg.getCityIdListList().isEmpty()) {
            // 获取全部城池列表
            for (CrossSuiTangCity city : cityActivityMgr.getCurCityMap(userId).values()) {
                SuiTang.SuiTangCityInfo.Builder builderInfo = SuiTang.SuiTangCityInfo.newBuilder();
                builderInfo.setCityInfo(parseSuiTangCityMsg(city));
                builderInfo.setBattleInfo(parseSuiTangBattlefieldMsg(city.getBattlefield(), city));
                builder.addCityList(builderInfo);
            }
        } else {
            for (int cityId : reqMsg.getCityIdListList()) {
                CrossSuiTangCity city = cityActivityMgr.getCurCity(userId, cityId);
                if (city == null) {
                    continue;
                }
                SuiTang.SuiTangCityInfo.Builder builderInfo = SuiTang.SuiTangCityInfo.newBuilder();
                builderInfo.setCityInfo(parseSuiTangCityMsg(city));
                builderInfo.setBattleInfo(parseSuiTangBattlefieldMsg(city.getBattlefield(), city));
                builder.addCityList(builderInfo);
            }
        }
        sendPacket(ClientProtocol.U_SUI_TANG_CITY_INFO, builder, userId);
    }

    /*
     * 获得城池战报
     */
    public void cityWarReport(long userId, boolean isSystemMsg) {
        SuiTang.SuiTangCityWarReportRespMsg.Builder respMsg = SuiTang.SuiTangCityWarReportRespMsg.newBuilder();
        respMsg.setRet(0);
        if (!isAble(userId)) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_CITY_WAR_REPORT, respMsg, userId);
            return;
        }

        CrossSuiTangUserData userData = getUserData(userId);
        Set<CrossSuiTangCityWarReportData> reportDataSet = new HashSet<>();
        if (isSystemMsg) {
            UserScene userScene = CrossSceneMgr.getUserScene(userId);
            if (userScene == null) {
                sendPacket(ClientProtocol.U_SUI_TANG_CITY_WAR_REPORT, respMsg, userId);
                return;
            }
            CrossSuiTangUserRound curUserRound = roundActivityMgr.getCurUserRound(userId);
            if (curUserRound == null) {
                sendPacket(ClientProtocol.U_SUI_TANG_CITY_WAR_REPORT, respMsg, userId);
                return;
            }

            List<Integer> sceneParam = new ArrayList<>();
            sceneParam = sceneKeyToList(userScene.getSceneId());
            eSuiTangWarType warTypeTemp = !sceneParam.isEmpty() && sceneParam.size() > 2 ? eSuiTangWarType.forValue(sceneParam.get(2)) : curUserRound.getWarType();
            int actGroupId = !sceneParam.isEmpty() && sceneParam.size() > 3 ? sceneParam.get(3) : curUserRound.getActGroupId();
            CrossSuiTangGroup suiTangGroup = groupActivityMgr.getSuiTangGroup(warTypeTemp, actGroupId);
            if (suiTangGroup == null) {
                sendPacket(ClientProtocol.U_SUI_TANG_CITY_WAR_REPORT, respMsg, userId);
                return;
            }

            for (String unionId : suiTangGroup.getUnionMap().keySet()) {
                List<CrossSuiTangCityWarReportData> cityWarReportDataList = cityWarReportMap.get(unionId);
                if (cityWarReportDataList != null && !cityWarReportDataList.isEmpty()) {
                    reportDataSet.addAll(cityWarReportDataList);
                }
            }
        } else {
            List<CrossSuiTangCityWarReportData> cityWarReportDataList = cityWarReportMap.get(userData.getUnionUid());
            if (cityWarReportDataList != null && !cityWarReportDataList.isEmpty()) {
                reportDataSet.addAll(cityWarReportDataList);
            }
        }

        if (reportDataSet.isEmpty()) {
            sendPacket(ClientProtocol.U_SUI_TANG_CITY_WAR_REPORT, respMsg, userId);
            return;
        }

        List<CrossSuiTangCityWarReportData> list = new ArrayList<>(reportDataSet);
//        if (isSystemMsg) {
            list.sort(Comparator.comparing(CrossSuiTangCityWarReportData::getTime));
//        }

        int count = 0;
        for (int i = list.size() - 1; i >= 0; i--) {
            CrossSuiTangCityWarReportData report = list.get(i);
            if (count >= config.getParamConfig().getSuiTangCityBattleReportNumLimit()) {
                break;
            }
            if (isSystemMsg || Objects.equals(report.getDefCampId(), userData.getUnionUid()) || report.getAtkCampId().contains(userData.getUnionUid())) {
                count++;
                SuiTang.SuiTangCityWarReportMsg.Builder tempMsg = SuiTang.SuiTangCityWarReportMsg.newBuilder();
                for (String atkCampId : report.getAtkCampId()) {
                    tempMsg.addAtkUnionId(atkCampId);
                }
                tempMsg.setDefUnionId(report.getDefCampId());
                tempMsg.setType(report.getType());
                tempMsg.setCityId(report.getCityId());
                tempMsg.setTime(report.getTime());
                for (CrossSuiTangBattlefieldRank atkRank : report.getAtkRankList()) {
                    tempMsg.addAtkRank(parseSuiTangBattlefieldRankMsg(atkRank));
                }
                for (CrossSuiTangBattlefieldRank defRank : report.getDefRankList()) {
                    tempMsg.addDefRank(parseSuiTangBattlefieldRankMsg(defRank));
                }
                tempMsg.setWinUnionId(report.getWinCampId());
                respMsg.addList(tempMsg);
            }
        }
        syncActivityMgr.readRedDotByCmd(userId, eSuiTangRedDotType.Type3_CityWarReport.getValue());
        syncActivityMgr.readRedDotByCmd(userId, eSuiTangRedDotType.Type2_UserWarReport.getValue());
        sendPacket(ClientProtocol.U_SUI_TANG_CITY_WAR_REPORT, respMsg, userId);
    }

    /*
     * 获得个人战报
     */
    public void userWarReport(long userId) {
        SuiTang.SuiTangUserWarReportRespMsg.Builder respMsg = SuiTang.SuiTangUserWarReportRespMsg.newBuilder();
        respMsg.setRet(0);
        if (!isAble(userId)) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_CITY_WAR_REPORT, respMsg, userId);
            return;
        }

        List<CrossSuiTangUserWarReportData> reportDataList = userWarReportDataMap.get(userId);
        if (reportDataList == null || reportDataList.isEmpty()) {
            sendPacket(ClientProtocol.U_SUI_TANG_CITY_WAR_REPORT, respMsg, userId);
            return;
        }

        List<CrossSuiTangUserWarReportData> list = new ArrayList<>(reportDataList);
        int count = 0;
        for (int i = list.size() - 1; i >= 0; i--) {
            CrossSuiTangUserWarReportData report = list.get(i);
            if (count >= config.getParamConfig().getSuiTangPersonalBattleReportNumLimit()) {
                break;
            }
            if (report.getUserIdAct() == userId) {
                count++;
                SuiTang.SuiTangUserWarReportMsg.Builder tempMsg = SuiTang.SuiTangUserWarReportMsg.newBuilder();
                tempMsg.setNo(0);
                tempMsg.setMySoldierNum(report.getActSoldierNum());
                tempMsg.setOtherSoldierNum(report.getDefSoldierNum());
                tempMsg.setTime(report.getTime());
                tempMsg.setAddZhanGong(report.getActZhanGong());
                tempMsg.setKillSoldierNum(report.getDefDieSoldierNum());
                tempMsg.setCityId(report.getCityId());
                tempMsg.setIsWin(report.getWinUserId() == 2);
                tempMsg.setCostSoldierNum(report.getActDieSoldierNum());
                tempMsg.setMyAddition(report.getActAddition());
                tempMsg.setOtherAddition(report.getDefAddition());
                if (report.getUserIdDef() != 0) {
                    UserBaseInfo otherUserBaseInfo = CrossUserMgr.getUserBaseInfo(report.getUserIdDef());
                    if (otherUserBaseInfo != null) {
                        tempMsg.setOtherBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(otherUserBaseInfo));
                    }
                }
                tempMsg.setOtherUserId(report.getUserIdDef());
                tempMsg.setCityUnionId(report.getCityUnionId());
                respMsg.addList(tempMsg);
            } else if (report.getUserIdDef() == userId) {
                count++;
                SuiTang.SuiTangUserWarReportMsg.Builder tempMsg = SuiTang.SuiTangUserWarReportMsg.newBuilder();
                tempMsg.setNo(0);
                tempMsg.setMySoldierNum(report.getDefSoldierNum());
                tempMsg.setOtherSoldierNum(report.getActSoldierNum());
                tempMsg.setTime(report.getTime());
                tempMsg.setAddZhanGong(report.getDefZhanGong());
                tempMsg.setKillSoldierNum(report.getActDieSoldierNum());
                tempMsg.setCityId(report.getCityId());
                tempMsg.setIsWin(report.getWinUserId() != 2);
                tempMsg.setCostSoldierNum(report.getDefDieSoldierNum());
                tempMsg.setMyAddition(report.getDefAddition());
                tempMsg.setOtherAddition(report.getActAddition());
                if (report.getUserIdAct() != 0) {
                    UserBaseInfo otherUserBaseInfo = CrossUserMgr.getUserBaseInfo(report.getUserIdAct());
                    if (otherUserBaseInfo != null) {
                        tempMsg.setOtherBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(otherUserBaseInfo));
                    }
                }
                tempMsg.setOtherUserId(report.getUserIdAct());
                tempMsg.setCityUnionId(report.getCityUnionId());
                respMsg.addList(tempMsg);
            }
        }
        syncActivityMgr.readRedDotByCmd(userId, eSuiTangRedDotType.Type2_UserWarReport.getValue());
        syncActivityMgr.readRedDotByCmd(userId, eSuiTangRedDotType.Type3_CityWarReport.getValue());
        sendPacket(ClientProtocol.U_SUI_TANG_USER_WAR_REPORT, respMsg, userId);
    }

    //同步玩家身上的数据
    public void syncUserData(long userId, SuiTang.SuiTangUserDataSyncMsg reqMsg) {
        SuiTang.SuiTangUserDataSyncMsg.Builder respMsg = reqMsg.toBuilder();
        respMsg.setWinnerId(crossSuiTangData.getProcess2WinUserId());
        sendPacket(ClientProtocol.U_SUI_TANG_USER_DATA_SYNC, respMsg, userId);
    }

    public void attackByCmd(long userId, SuiTang.SuiTangAttackReqMsg reqMsg) {
        if (!this.isBattleStep()) {
            SuiTang.SuiTangAttackRespMsg.Builder builder = SuiTang.SuiTangAttackRespMsg.newBuilder();
            builder.setRet(GameErrorCode.E_SUI_TANG_NO_OPERATE_TIME);
            sendPacket(ClientProtocol.U_SUI_TANG_ATTACK, builder, userId);
            return;
        }
        if (!isAble(userId)) {
            SuiTang.SuiTangAttackRespMsg.Builder builder = SuiTang.SuiTangAttackRespMsg.newBuilder();
            builder.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_ATTACK, builder, userId);
            return;
        }
        if (battleActivityMgr.isOut(userId)) {
            SuiTang.SuiTangAttackRespMsg.Builder builder = SuiTang.SuiTangAttackRespMsg.newBuilder();
            builder.setRet(GameErrorCode.E_SUI_TANG_IS_OUT);
            sendPacket(ClientProtocol.U_SUI_TANG_ATTACK, builder, userId);
            return;
        }

        CrossSuiTangCity city = cityActivityMgr.getUserCity(userId, reqMsg.getCityId());
        if (city == null) {
            SuiTang.SuiTangAttackRespMsg.Builder builder = SuiTang.SuiTangAttackRespMsg.newBuilder();
            builder.setRet(GameErrorCode.E_SUI_TANG_CITY_NO_EXIST);
            sendPacket(ClientProtocol.U_SUI_TANG_ATTACK, builder, userId);
            return;
        }
        do {
            CrossSuiTangBattlefield battlefield = city.getBattlefield();
            if (battlefield == null) {
                break;
            }
            CrossSuiTangBattlefieldTeam team = battlefield.getDefTeamMap().get(reqMsg.getTeamNo());
            boolean isNpc = team != null && team.getTeam() == null;
            CrossSuiTangBattleResult result = battleActivityMgr.handleBattle(city, userId, reqMsg.getTeamNo(), isNpc);
            if (result == null) {
                break;
            }
            SuiTang.SuiTangAttackRespMsg.Builder builder = SuiTang.SuiTangAttackRespMsg.newBuilder();
            builder.setRet(0);
            //builder.setBattlefield(parseSuiTangBattlefieldMsg(city.getBattlefield(), city));
            sendPacket(ClientProtocol.U_SUI_TANG_ATTACK, builder, userId);
            return;
        } while (false);

        SuiTang.SuiTangAttackRespMsg.Builder builder = SuiTang.SuiTangAttackRespMsg.newBuilder();
        builder.setRet(GameErrorCode.E_SUI_TANG_BATTLE_FAIL);
        builder.setBattlefield(parseSuiTangBattlefieldMsg(city.getBattlefield(), city));
        sendPacket(ClientProtocol.U_SUI_TANG_ATTACK, builder, userId);
    }

    /*
     * clearMoveTargetCityCmd
     */
    public void clearMoveTargetCityCmd(long userId) {
        SuiTang.SuiTangClearTargetCityRespMsg.Builder builder = SuiTang.SuiTangClearTargetCityRespMsg.newBuilder();
        int ret = 0;
        do {
            if (!isAble(userId)) {
                ret = GameErrorCode.E_SUI_TANG_NO_ABLE;
                break;
            }
            CrossSuiTangUserData userData = getUserData(userId);
            CrossSuiTangTeam team = userData.getTeam();
            if (team == null) {
                ret = GameErrorCode.E_SUI_TANG_PARAM_ERR;
                break;
            }

            team.setTargetCityId(0);
            syncActivityMgr.syncTeamToSelf(team);
        } while (false);

        builder.setRet(ret);
        sendPacket(ClientProtocol.U_SUI_TANG_CLEAR_TARGET_CITY, builder, userId);
    }

    /*
     * getUserRankZhanGongDetailCmd
     */
    public void getUserRankZhanGongDetailCmd(long userId, long reqUserId) {
        SuiTang.SuiTangUserZhanGongDetailRespMsg.Builder builder = SuiTang.SuiTangUserZhanGongDetailRespMsg.newBuilder();
        int ret = 0;
        do {
            CrossSuiTangUserData userData = getUserData(reqUserId);
            if (userData == null) {
                ret = GameErrorCode.E_SUI_TANG_PARAM_ERR;
                break;
            }
            Map<Integer, CrossSuiTangUserRound> userRoundMap = userData.getUserRoundMap();
            for (CrossSuiTangUserRound value : userRoundMap.values()) {
                SuiTang.SuiTangUserZhanGong.Builder builderTemp = SuiTang.SuiTangUserZhanGong.newBuilder();
                builderTemp.setRound(value.getRound());
                builderTemp.setZhanGong(value.getScore().longValue());
                builderTemp.setWarType(value.getWarType().getType());
                builder.addValue(builderTemp);
            }
        } while (false);

        builder.setRet(ret);
        sendPacket(ClientProtocol.U_SUI_TANG_USER_ZHAN_GONG_DETAIL, builder, userId);
    }

    /*
     * getUnionRankDetailCmd
     */
    public void getUnionRankDetailCmd(long userId, String unionId) {
        SuiTang.SuiTangUnionScoreDetailRespMsg.Builder builder = SuiTang.SuiTangUnionScoreDetailRespMsg.newBuilder();
        int ret = 0;
        do {
            Map<Integer, CrossSuiTangUnionRound> unionRoundMap = unionActivityMgr.getUnionRoundMap(unionId);
            if (unionRoundMap == null) {
                ret = GameErrorCode.E_SUI_TANG_PARAM_ERR;
                break;
            }
            CrossSuiTangUnionJoinData unionJoinData = unionJoinDataMap.get(unionId);
            if (unionJoinData == null) {
                ret = GameErrorCode.E_SUI_TANG_PARAM_ERR;
                break;
            }
//            List<UserYRank> sortUserRankList = CrossYRankMgr.getSortUnionContributionList(getConfig().getActivityId(), groupId,
//                    String.valueOf(eGamePlayerEventType.SuiTangUnionScoreRank.getValue()),
//                    String.valueOf(eGamePlayerEventType.SuiTangUserZhanGongRank.getValue()), unionJoinData.getUnionUid());
            for (CrossSuiTangUnionJoinMember member : unionJoinData.getMemberMap().values()) {
                CrossSuiTangUserData userData = getUserData(member.getUserId());
                if (userData == null) {
                    continue;
                }
                long zhanGong = userData.getZhanGong();
                if (zhanGong == 0) {
                    continue;
                }
                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(member.getUserId());
                if (userBaseInfo == null) {
                    continue;
                }
                String nickname = userBaseInfo.getNickName();
                SuiTang.SuiTangUnionMemberZhanGongTemp.Builder memberBuilder = SuiTang.SuiTangUnionMemberZhanGongTemp.newBuilder();
                memberBuilder.setNickname(nickname);
                memberBuilder.setZhanGong(zhanGong);

                RankProto.RankListMsg.Builder rankBuilder = CrossYRankCacheMgr.getUserRankList(getConfig().getActivityId(), groupId,
                        String.valueOf(eGamePlayerEventType.SuiTangUserZhanGongRank.getValue()));
                int rankNum = CrossYRankCacheMgr.getUserRank(getConfig().getActivityId(), groupId,
                        String.valueOf(eGamePlayerEventType.SuiTangUserZhanGongRank.getValue()), rankBuilder, member.getUserId());

                memberBuilder.setRank(rankNum);
                builder.addMemberList(memberBuilder);
            }
            for (CrossSuiTangUnionRound unionRound : unionRoundMap.values()) {
                SuiTang.SuiTangUnionBattlefieldDetailTemp.Builder builderTemp = SuiTang.SuiTangUnionBattlefieldDetailTemp.newBuilder();
                builderTemp.setActGroupId(unionRound.getActGroupId());
                builderTemp.setRank(unionRound.getRank());
                int rankScore = getConfig().getRankScore(unionRound.getRound(), unionRound.getWarType().getType(), unionRound.getRank());
                builderTemp.setUnionScore(rankScore);
                builderTemp.setCityScore(unionRound.getCurrentCityScore().longValue());
                builderTemp.setIsOut(unionRound.isOut());
                builderTemp.setWarType(unionRound.getWarType().getType());
                builder.addBattlefieldList(builderTemp);
            }
        } while (false);

        builder.setRet(ret);
        sendPacket(ClientProtocol.U_SUI_TANG_UNION_SCORE_DETAIL, builder, userId);
    }

    /*
     * getCityTeamByCmd
     */
    public void getCityTeamByCmd(long userId, SuiTang.SuiTangCityReqMsg reqMsg) {
        // 解析参数
        Map<Integer, Long> cityTimeMap = new ConcurrentHashMap<>();
        for (SuiTang.SuiTangSyncCityMsg cityTeamMsg : reqMsg.getCityInfoList()) {
            cityTimeMap.put(cityTeamMsg.getCityId(), cityTeamMsg.getTime());
        }

        long now = System.currentTimeMillis();
        List<CrossSuiTangTeam> cityTeams = cityActivityMgr.getCityTeam(userId, cityTimeMap, now);

        SuiTang.SuiTangCityRespMsg.Builder builder = SuiTang.SuiTangCityRespMsg.newBuilder();
        for (SuiTang.SuiTangSyncCityMsg cityMsg : reqMsg.getCityInfoList()) {
            builder.addCityInfo(cityMsg.toBuilder().setTime(now));
        }
        for (CrossSuiTangTeam team : cityTeams) {
            builder.addTeam(parseSuiTangTeamMsg(team));
        }
        sendPacket(ClientProtocol.U_SUI_TANG_SYNC_CITY_TEAM, builder, userId);
    }

    /*
     * getDataByCmd
     */
    public void getDataByCmd(long userId, boolean isOb, eSuiTangWarType warType, int actGroupId, int titleId, int honoraryTitle,
                             SuiTang.CrossSuiTangTeamParam teamParam) {
        SuiTang.SuiTangGetDataRespMsg.Builder builder = SuiTang.SuiTangGetDataRespMsg.newBuilder();
        CrossSuiTangUserRound curUserRound = roundActivityMgr.getCurUserRound(userId);
        eSuiTangWarType warTypeTemp = isOb ? warType : curUserRound.getWarType();
        int actGroupIdTemp = isOb ? actGroupId : curUserRound.getActGroupId();
        if (!isAble(userId)) {
            builder.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            builder.setWarType(warTypeTemp.getType());
        } else {
            CrossSuiTangUserData userData = getUserData(userId);
            // 锁一下身份等级和财神等级
            if (userData.getUserBaseInfo().getTitleId() == 0 && userData.getUserBaseInfo().getHonoraryTitle() == 0) {
                // 锁过了不再锁
                userData.getUserBaseInfo().setTitleId(titleId);
                userData.getUserBaseInfo().setHonoraryTitle(honoraryTitle);
                userData.setUpdateOption();
                barracksActivityMgr.refreshTeam(userData);
                if ((userData.getTeam().getCityId() == 0 || userData.getPatronsTotalAbility() == 0) && teamParam != null) {
                    // 有可能没有商会的玩家，加入了有资格的商会，此事玩家的队伍还没有同步过
                    firstSyncPatrons(userData, teamParam.getTotalAbility(), teamParam.getSoldierAddition(), teamParam.getPatronsNSum(), teamParam.getPatronsTotalNum());
                } else {
                    barracksActivityMgr.handleNextRound(userData);
                }
            }
            builder.setRet(0);
            builder.setWarType(warTypeTemp.getType());
            if (!isOb) {
                builder.addTeam(parseSuiTangTeamMsg(userData.getTeam()));
            }
            Map<Integer, CrossSuiTangCity> cityMap = cityActivityMgr.getCityMap(warTypeTemp, actGroupIdTemp);
            if (cityMap != null) {
                for (CrossSuiTangCity city : cityActivityMgr.getCityMap(warTypeTemp, actGroupIdTemp).values()) {
                    builder.addCity(parseSuiTangCityMsg(city));
                }
            }
            barracksActivityMgr.barracksCalc(userId);
            builder.setBarracks(parseSuiTangBarracksMsg(userId));
            if (cityActivityMgr.getCityEventMap(warTypeTemp, actGroupIdTemp) != null) {
                for (CrossSuiTangCityEvent event : cityActivityMgr.getCityEventMap(warTypeTemp, actGroupIdTemp).values()) {
                    builder.addEvent(parseSuiTangCityEventMsg(event));
                }
            }
            for (CrossSuiTangUnionJoinData unionData : unionJoinDataMap.values()) {
                CrossSuiTangUnionRound union = roundActivityMgr.getUnionRoundData(unionData.getUnionUid());
                if (union != null && union.getWarType() == warTypeTemp && union.getActGroupId() == actGroupIdTemp) {
                    builder.addUnionList(parseSuiTangUnionTempMsg(unionData));
                }
            }
            builder.setCommander(parseSuiTangCommanderDataSyncMsg(unionDataMap.get(userData.getUnionUid())));
            builder.setUnlockYinShan(cityActivityMgr.canOpenYinShanCity(warTypeTemp, actGroupIdTemp));
            builder.setTitleId(userData.getUserBaseInfo().getTitleId());
            builder.setHonoraryTitle(userData.getUserBaseInfo().getHonoraryTitle());
            builder.setActGroupId(actGroupIdTemp);
            enterScene(userId, eSceneType.SuiTangMap, 0, warTypeTemp, actGroupIdTemp, false);

            if (crossSuiTangData.getStep().getValue() == eSuiTangStage.Stage1Time.getValue()) {
                syncActivityMgr.addRedDot(getUserData(userId), eSuiTangRedDotType.Type4_YinDao);
            }

            // 同步待领奖数据
            syncActivityMgr.syncWaitReward(userData);
        }

        if (isOb) {
            sendPacket(ClientProtocol.U_SUI_TANG_GET_DATA_FOR_OB, builder, userId);
        } else {
            sendPacket(ClientProtocol.U_SUI_TANG_GET_DATA, builder, userId);
        }
    }

    /*
     * moveTeamByCmd
     */
    public void moveTeamByCmd(long userId, SuiTang.SuiTangMoveTeamReqMsg reqMsg) {
        if (!isAble(userId)) {
            SuiTang.SuiTangMoveTeamRespMsg.Builder builder = SuiTang.SuiTangMoveTeamRespMsg.newBuilder();
            builder.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_MOVE_TEAM, builder, userId);
            return;
        }

        CrossSuiTangUserData userData = getUserData(userId);
        if (battleActivityMgr.isOut(userId)) {
            SuiTang.SuiTangMoveTeamRespMsg.Builder builder = SuiTang.SuiTangMoveTeamRespMsg.newBuilder();
            builder.setRet(GameErrorCode.E_SUI_TANG_IS_OUT);
            builder.setTeam(parseSuiTangTeamMsg(userData.getTeam()));
            sendPacket(ClientProtocol.U_SUI_TANG_MOVE_TEAM, builder, userId);
            return;
        }

        int ret = mapActivityMgr.moveToCity(userData.getTeam(), reqMsg.getToCityId());
        SuiTang.SuiTangMoveTeamRespMsg.Builder builder = SuiTang.SuiTangMoveTeamRespMsg.newBuilder();
        builder.setRet(ret);
        builder.setTeam(parseSuiTangTeamMsg(userData.getTeam()));
        sendPacket(ClientProtocol.U_SUI_TANG_MOVE_TEAM, builder, userId);
    }

    /*
     * speedUpByCmd
     */
    public void speedUpByCmd(long userId, int times) {
        int ret = 0;
        do {
            if (!isAble(userId)) {
                ret = GameErrorCode.E_SUI_TANG_NO_ABLE;
                break;
            }

            ret = mapActivityMgr.moveSpeedUp(userId);
            if (ret != 0) {
                break;
            }
        } while (false);

        SuiTang.SuiTangMoveSpeedUpRespMsg.Builder resp = SuiTang.SuiTangMoveSpeedUpRespMsg.newBuilder();
        resp.setRet(ret);
        CrossSuiTangUserData userData = getUserData(userId);
        CrossSuiTangTeam team = userData.getTeam();
        SuiTang.CrossSuiTangMoveSpeedUpRespMsg.Builder builder = SuiTang.CrossSuiTangMoveSpeedUpRespMsg.newBuilder();
        builder.setReqTimes(times);
        if (team != null) {
            builder.setRealTimes(team.getSpeedUpNum());
            resp.setTeam(parseSuiTangTeamMsg(team));
        }
        builder.setResp(resp);
        sendPacket(GameProtocol.S_SUI_TANG_MOVE_SPEED_UP_FROM_CROSS, builder, userId);
    }

    /*
     * syncPatronsByCmd
     */
    public void syncPatronsByCmd(SuiTang.CrossSuiTangUpdatePatronsReqMsg reqMsg) {
        SuiTang.SuiTangUpdateAbilityRespMsg.Builder respMsg = SuiTang.SuiTangUpdateAbilityRespMsg.newBuilder();
        if (!isAble(reqMsg.getUserId())) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_UPDATE_PATRONS_ABILITY, respMsg, reqMsg.getUserId());
            return;
        }
        long totalAbility = getUserData(reqMsg.getUserId()).getPatronsTotalAbility();
        int ret = barracksActivityMgr.syncPatrons(reqMsg.getUserId(),
                false,
                reqMsg.getTotalAbility(),
                reqMsg.getSoldierAddition(),
                reqMsg.getPatronsNSum(),
                reqMsg.getPatronsTotalNum(),
                reqMsg.getIsRefreshMaxSoldier()
        );
        if (ret == 0) {
            CrossSuiTangUnionJoinMember unionJoinMember = unionActivityMgr.getUnionJoinMember(getUserData(reqMsg.getUserId()).getUnionUid(), reqMsg.getUserId());
            if (unionJoinMember != null) {
                unionJoinMember.setTopAbility(reqMsg.getPatronsTotalAbility());
                unionActivityMgr.getUnionJoin(getUserData(reqMsg.getUserId()).getUnionUid()).setUpdateOption();
            }
        }

        respMsg.setRet(ret);
        respMsg.setTeam(parseSuiTangTeamMsg(barracksActivityMgr.getTeam(reqMsg.getUserId())));
        respMsg.setBarracks(parseSuiTangBarracksMsg(reqMsg.getUserId()));
        sendPacket(ClientProtocol.U_SUI_TANG_UPDATE_PATRONS_ABILITY, respMsg, reqMsg.getUserId());
        logActivityMgr.addSyncAbilityLog(reqMsg.getUserId(), totalAbility);
    }


    /**
     * 获取自动设置
     */
    public void autoSettingReqByCmd(long userId) {
        SuiTang.SuiTangAutoSettingRespMsg.Builder respMsg = SuiTang.SuiTangAutoSettingRespMsg.newBuilder();
        respMsg.setRet(0);

        if (!isAble(userId)) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_AUTO_SETTING_REQ, respMsg, userId);
            return;
        }

        CrossSuiTangUserData userData = getUserData(userId);
        if (userData == null) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_AUTO_SETTING_REQ, respMsg, userId);
            return;
        }
        String unionUid = userData.getUnionUid();
        if (unionUid == null || unionUid.isEmpty()) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_AUTO_SETTING_REQ, respMsg, userId);
            return;
        }

        CrossSuiTangAutoSettingData autoSettingData = userData.getAutoSettingData();
        respMsg.setAutoSpeed(autoSettingData.isAutoSpeed());
        respMsg.setIngotsTimes(autoSettingData.getIngotsTimes());
        respMsg.setSpeedLimit(autoSettingData.getSpeedLimit());

        sendPacket(ClientProtocol.U_SUI_TANG_AUTO_SETTING_REQ, respMsg, userId);
    }

    /**
     * 自动设置保存
     */
    public void autoSettingSaveByCmd(long userId, SuiTang.CrossSuiTangAutoSettingSaveReqMsg reqMsg) {
        SuiTang.SuiTangAutoSettingSaveRespMsg.Builder respMsg = SuiTang.SuiTangAutoSettingSaveRespMsg.newBuilder();
        respMsg.setRet(0);

        if (!isAble(userId)) {
            respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
            sendPacket(ClientProtocol.U_SUI_TANG_AUTO_SETTING_SAVE, respMsg, userId);
            return;
        }

        synchronized (getMapActivityMgr().getPlayerLock(userId)) {
            CrossSuiTangUserData userData = getUserData(userId);
            if (userData == null) {
                respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
                sendPacket(ClientProtocol.U_SUI_TANG_AUTO_SETTING_SAVE, respMsg, userId);
                return;
            }
            String unionUid = userData.getUnionUid();
            if (unionUid == null || unionUid.isEmpty()) {
                respMsg.setRet(GameErrorCode.E_SUI_TANG_NO_ABLE);
                sendPacket(ClientProtocol.U_SUI_TANG_AUTO_SETTING_SAVE, respMsg, userId);
                return;
            }
            if (!config.getParamConfig().getMoveAutoTimeList().contains(reqMsg.getReq().getSpeedLimit())) {
                respMsg.setRet(GameErrorCode.E_ERROR_PARAMETER);
                sendPacket(ClientProtocol.U_SUI_TANG_AUTO_SETTING_SAVE, respMsg, userId);
                return;
            }

            CrossSuiTangAutoSettingData autoSettingData = userData.getAutoSettingData();
            autoSettingData.setAutoSpeed(reqMsg.getReq().getAutoSpeed());
            autoSettingData.setSpeedLimit(reqMsg.getReq().getSpeedLimit());

            userData.setUpdateOption();
        }
        respMsg.setRet(0);
        sendPacket(ClientProtocol.U_SUI_TANG_AUTO_SETTING_SAVE, respMsg, userId);
    }


    /**
     * 自动设置元宝操作
     */
    public int autoSettingIngotsOperateByCmd(long userId, SuiTang.CrossSuiTangAutoSettingIngotsOperateReqMsg reqMsg) {
        SuiTang.CrossSuiTangAutoSettingIngotOperateFromCrossMsg.Builder respMsg = SuiTang.CrossSuiTangAutoSettingIngotOperateFromCrossMsg.newBuilder();
        respMsg.setRet(0);

        if (!isAble(userId)) {
            return GameErrorCode.E_SUI_TANG_NO_ABLE;
        }

        CrossSuiTangUserData userData = getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_SUI_TANG_NO_ABLE;
        }
        String unionUid = userData.getUnionUid();
        if (unionUid == null || unionUid.isEmpty()) {
            return GameErrorCode.E_SUI_TANG_NO_ABLE;
        }

        CrossSuiTangAutoSettingData autoSettingData = userData.getAutoSettingData();

        if (autoSettingData.getIngotsTimes() + reqMsg.getReq().getOffsetIngotsTimes() > config.getParamConfig().getMoveAutoNum()) {
            return GameErrorCode.E_ERROR_PARAMETER;
        }

        // 旧的元宝次数
        long oldIngotsTimes = autoSettingData.getIngotsTimes();
        if (reqMsg.getReq().getOperateType() == 1) {
            // 增加
            autoSettingData.setIngotsTimes(autoSettingData.getIngotsTimes() + reqMsg.getReq().getOffsetIngotsTimes());
        } else if (reqMsg.getReq().getOperateType() == 2) {
            // 取回
            autoSettingData.setIngotsTimes(0);
        }
        // 新的元宝次数
        long newIngotsTimes = autoSettingData.getIngotsTimes();
        respMsg.setRet(0);
        respMsg.setUserId(userId);
        respMsg.setOperateType(reqMsg.getReq().getOperateType());
        respMsg.setOffsetIngotsTimes(Math.abs(newIngotsTimes - oldIngotsTimes));
        respMsg.setIngotsTimes(autoSettingData.getIngotsTimes());
        sendPacket(GameProtocol.S_SUI_TANG_AUTO_SETTING_INGOTS_OPERATE_FROM_CROSS, respMsg, userId);
        return 0;
    }



    /*
     * getBattleField
     */
    private int getBattleField(long userId, int cityId) {
        if (!ActivityMgr.activityInTime(config.getActivityInfo())) {
            return GameErrorCode.E_SUI_TANG_NO_OPERATE_TIME;
        }
        Map<Integer, CrossSuiTangCity> curCityMap = barracksActivityMgr.getCurCityMap(userId);
        if (curCityMap == null || curCityMap.isEmpty()) {
            return GameErrorCode.E_SUI_TANG_PARAM_ERR;
        }
        CrossSuiTangCity city = barracksActivityMgr.getCurCityMap(userId).get(cityId);
        if (city == null) {
            return GameErrorCode.E_SUI_TANG_PARAM_ERR;
        }
        CrossSuiTangBattlefield battlefield = city.getBattlefield();
        if (battlefield == null) {
            return GameErrorCode.E_SUI_TANG_NO_BATTLE;
        }

        SuiTang.SuiTangEnterBattlefieldRespMsg.Builder builder = SuiTang.SuiTangEnterBattlefieldRespMsg.newBuilder();
        builder.setRet(0);
        builder.setBattlefield(parseSuiTangBattlefieldMsg(battlefield, city));

        // 进入场景
        enterScene(userId, eSceneType.SuiTangBattlefield, cityId, city.getWarType(), city.getActGroupId(), true);
        sendPacket(ClientProtocol.U_SUI_TANG_GET_BATTLE_FIELD, builder, userId);
        return 0;
    }

    /*
     * 退出战场
     */
    public void quitBattleField(long userId) {
        // 退出战场，进入大地图场景
        if (!isAble(userId)) {
            return;
        }
        CrossSuiTangUserRound curUserRound = roundActivityMgr.getCurUserRound(userId);
        if (curUserRound == null) {
            return;
        }
        enterScene(userId, eSceneType.SuiTangMap, 0, curUserRound.getWarType(), curUserRound.getActGroupId(), false);
    }

    /*
     * 进入场景
     */
    public void enterScene(long userId, eSceneType scene, int cityId, eSuiTangWarType warType, int actGroupId, boolean isRemoveOldScene) {
        // 进入场景 cityId 为 0，表示在战场地图
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
        if (userBaseInfo != null) {
            ScenePlayerInfo scenePlayerInfo = new ScenePlayerInfo(userBaseInfo.getServerId(), userId, userBaseInfo.getNickName(), userBaseInfo.getDecoration());
            UserScene userScene = new UserScene(
                    config.getActivityInfo().getActivityId(),
                    scene.getValue(),
                    getSceneKey(cityId, warType, actGroupId),
                    userId,
                    scenePlayerInfo,
                    System.currentTimeMillis());
            CrossSceneMgr.enterScene(userScene, false);
        }
    }

    /*
     * getBattlefieldUserIdList
     */
    public List<Long> getSceneUserIdList(eSceneType scene, int cityId, eSuiTangWarType warType, int actGroupId) {
        String sceneKey = getSceneKey(cityId, warType, actGroupId);
        List<UserScene> sceneUserList = CrossSceneMgr.getSceneUserList(
                config.getActivityInfo().getActivityId(),
                scene.getValue(),
                sceneKey,
                23333);
        return sceneUserList.stream().filter(item -> isAble(item.getUserId())).mapToLong(UserScene::getUserId).boxed().collect(Collectors.toList());
    }

    /*
     * getBattlefieldSceneKey
     */
    public String getSceneKey(int cityId, eSuiTangWarType warType, int actGroupId) {
        // cityId 为 0，表示在大地图
        return groupId + "-" + cityId + "-" + warType.getType() + "-" + actGroupId;
    }

    public List<Integer> sceneKeyToList(String sceneKey) {
        // cityId 为 0，表示在大地图
        return StringUtils.stringToIntegerList(sceneKey, "-");
    }

    /*
     * getTopTeam
     */
    private List<CrossSuiTangTeam> getTopTeam() {
        List<CrossSuiTangTeam> ret = new ArrayList<>();
        return ret;
    }

    /**
     * 玩家是否在界面内
     */
    public boolean isInActivity(CrossSuiTangUserData data, long now) {
        if (!isAble(data.getUserId())) {
            return false; // 无资格的都进不了界面
        }
        if (getNpcTestActivityMgr().isNpc(data.getUserId())) {
            return false;
        }
        if (now - data.getLastReqTime() < DateHelper.MINUTE_MILLIONS * 3) {
            return true; // 3分钟内有请求的都当他在线
        }
        //logger.debug("【隋唐】触发同步，但玩家超过了请求时长，玩家id：{}", data.getUserId());
        return false;
    }

    /**
     * 玩家在当前分组
     */
    public boolean isInActivityGroup(CrossSuiTangUserData data, eSuiTangWarType warType, int actGroupId) {
        if (!isAble(data.getUserId())) {
            return false; // 无资格的都进不了界面
        }

        UserScene userScene = CrossSceneMgr.getUserScene(data.getUserId());
        if (userScene == null) {
            //logger.info("【隋唐】玩家场景为空，userId:{},warType:{},actGroupId:{}", data.getUserId(), warType.getName(), actGroupId);
            return false;
        }
        List<Integer> list = sceneKeyToList(userScene.getSceneId());
        if (list == null || list.size() < 4) {
            return false;
        }

        int warTypeTemp = list.get(2);
        int actGroupIdTemp = list.get(3);

        return warType.getType() == warTypeTemp && actGroupId == actGroupIdTemp;
    }

    /**
     * 设置请求时间
     */
    public void setLastReqTime(long userId) {
        if (userId <= 0 || !isAble(userId)) {
            return;
        }
        CrossSuiTangUserData userData = getUserData(userId);
        userData.setLastReqTime(System.currentTimeMillis());
    }

    private void initUserData(long userId) {
        CrossSuiTangUserData userData = CrossSuiTangUserData.initCrossSuiTangUserData(config.getActivityId(), groupId, userId);
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
//        if (userBaseInfo == null) {
//            return;
//        }
        if (userBaseInfo != null && !crossSuiTangData.getLockUnion()) {
            userData.setUnionUid(userBaseInfo.getUnionUid());
            // userData.setUserBaseInfo(new CrossSuiTangUserBaseInfo(userBaseInfo.getTitleId(), StringUtils.parseInt(userBaseInfo.getDecoration())));
        }
//        else if (npcTestActivityMgr.isNpcMode()) {
//            CrossUserBaseInfo crossNpcUserBaseInfo = CrossNpcUserMgr.getCrossNpcUserBaseInfo(userId);
//            userData.setUnionUid(crossNpcUserBaseInfo.getUserBaseInfo().getUnionUid());
//        }
        // 初始化数据

        // 默认加速时间点档位
        userData.getAutoSettingData().setSpeedLimit(config.getParamConfig().getMoveAutoTimeInit());


        userData.setInsertOption();
        userDataMap.put(userId, userData);
    }

    public CrossSuiTangUserData getUserData(long userId) {
        CrossSuiTangUserData userData = userDataMap.get(userId);
        if (userData == null) {
            initUserData(userId);
        }
        return userDataMap.get(userId);
    }

    public Map<String, CrossSuiTangUnionJoinData> getUnionJoinDataMap() {
        return unionJoinDataMap;
    }

    public void setUnionJoinDataMap(Map<String, CrossSuiTangUnionJoinData> unionJoinDataMap) {
        this.unionJoinDataMap = unionJoinDataMap;
    }

    public CrossSuiTangData getCrossSuiTangData() {
        return crossSuiTangData;
    }

    public void setCrossSuiTangData(CrossSuiTangData crossSuiTangData) {
        this.crossSuiTangData = crossSuiTangData;
    }

//    public CrossSuiTangRankListModel getUnionRankMap() {
//        return unionRankMap;
//    }
//
//    public void setUnionRankMap(CrossSuiTangRankListModel unionRankMap) {
//        this.unionRankMap = unionRankMap;
//    }

    public Map<eSuiTangWarType, Map<Integer, CrossSuiTangRankListModel>> getWarUnionRankMap() {
        return warUnionRankMap;
    }

    public void setWarUnionRankMap(Map<eSuiTangWarType, Map<Integer, CrossSuiTangRankListModel>> warUnionRankMap) {
        this.warUnionRankMap = warUnionRankMap;
    }

    public Map<Long, CrossSuiTangUserData> getUserDataMap() {
        return userDataMap;
    }

    public void setUserDataMap(Map<Long, CrossSuiTangUserData> userDataMap) {
        this.userDataMap = userDataMap;
    }

    public Map<String, CrossSuiTangUnionData> getUnionDataMap() {
        return unionDataMap;
    }

    public void setUnionDataMap(Map<String, CrossSuiTangUnionData> unionDataMap) {
        this.unionDataMap = unionDataMap;
    }

    public int getGroupId() {
        return groupId;
    }

    public void setGroupId(int groupId) {
        this.groupId = groupId;
    }

    public eSuiTangWarType getUserWarType(long userId) {
        return roundActivityMgr.getUserWarType(userId);
    }

    public eSuiTangWarType getUnionWarType(String unionId) {
        return roundActivityMgr.getUnionWarType(unionId);
    }

    public CrossSuiTangGroupActivityMgr getGroupActivityMgr() {
        return groupActivityMgr;
    }

    public CrossSuiTangCityActivityMgr getCityActivityMgr() {
        return cityActivityMgr;
    }

    public void setCityActivityMgr(CrossSuiTangCityActivityMgr cityActivityMgr) {
        this.cityActivityMgr = cityActivityMgr;
    }

    public boolean isAble(long userId) {
        return userDataMap != null && userDataMap.containsKey(userId);
    }

    public SuiTang.SuiTangBarracksMsg.Builder parseSuiTangBarracksMsg(long userId) {
        SuiTang.SuiTangBarracksMsg.Builder builder = SuiTang.SuiTangBarracksMsg.newBuilder();
        CrossSuiTangUserData userData = getUserData(userId);
        CrossSuiTangBarracks barracks = userData.getBarracks();
        builder.setReadyNum(barracks.getReadyNum());
        builder.setReadyMaxNum(barracks.getReadyMaxNum());
        builder.setCreateTime(barracks.getCreateTime());
        builder.setCreateSpeed(DateHelper.MINUTE_MILLIONS);
        builder.setCreateCount(barracks.getCreateSpeed());
        builder.setTotalAbility(userData.getPatronsTotalAbility());
        CrossSuiTangUnionJoinMember unionJoinMember = unionActivityMgr.getUnionJoinMember(userData.getUnionUid(), userData.getUserId());
        if (unionJoinMember != null) {
            builder.setTotalAbility(unionJoinMember.getTopAbility());
        }
        //builder.setBuffId(barracksActivityMgr.getBuff(userData.getUnionUid(), eSuiTangBuffType.Type7_ReadySoldierMaxNum));

        return builder;
    }

    public SuiTang.SuiTangBattlefieldMsg.Builder parseSuiTangBattlefieldMsg(CrossSuiTangBattlefield battlefield,
                                                                            CrossSuiTangCity city) {
        SuiTang.SuiTangBattlefieldMsg.Builder builder = SuiTang.SuiTangBattlefieldMsg.newBuilder();
        builder.setCityId(city.getCityId());
        for (CrossSuiTangBattlefieldTeam team : battlefield.getAtkTeamMap().values()) {
            builder.addAtk(parseSuiTangBattleTeamMsg(team, city));
        }
        for (CrossSuiTangBattlefieldTeam team : battlefield.getDefTeamMap().values()) {
            builder.addDef(parseSuiTangBattleTeamMsg(team, city));
        }
        String scene = getSceneKey(city.getCityId(), city.getWarType(), city.getActGroupId());
        if (battleActivityMgr.getBattleResultMap().get(scene) != null) {
            for (CrossSuiTangBattleResult ret : battleActivityMgr.getBattleResultMap().get(scene)) {
                builder.addFight(parseSuiTangBattleFightTeamMsg(ret, city));
            }
        }

        return builder;
    }

    public SuiTang.SuiTangBattlefieldMsg.Builder parseSuiTangBattlefieldMsgForSync(CrossSuiTangBattlefield battlefield,
                                                                                   CrossSuiTangCity city) {
        SuiTang.SuiTangBattlefieldMsg.Builder builder = SuiTang.SuiTangBattlefieldMsg.newBuilder();
        builder.setCityId(city.getCityId());
        for (CrossSuiTangBattlefieldTeam team : battlefield.getAtkTeamMap().values()) {
            builder.addAtk(parseSuiTangBattleTeamMsg(team, city));
        }
        for (CrossSuiTangBattlefieldTeam team : battlefield.getDefTeamMap().values()) {
            builder.addDef(parseSuiTangBattleTeamMsg(team, city));
        }
        String scene = getSceneKey(city.getCityId(), city.getWarType(), city.getActGroupId());
        if (battleActivityMgr.getBattleResultMap().get(scene) != null) {
            for (CrossSuiTangBattleResult ret : battleActivityMgr.getBattleResultMap().get(scene)) {
                builder.addFight(parseSuiTangBattleFightTeamMsg(ret, city));
            }
        }
        return builder;
    }

    public SuiTang.SuiTangBattlefieldTeamMsg.Builder parseSuiTangBattleTeamMsg(CrossSuiTangBattlefieldTeam team,
                                                                               CrossSuiTangCity city) {
        SuiTang.SuiTangBattlefieldTeamMsg.Builder builder = SuiTang.SuiTangBattlefieldTeamMsg.newBuilder();
        Map<Integer, SuiTangCityTypeConfig> cityTypeConfigMap = config.getCityTypeConfigMap();
        if (cityTypeConfigMap == null || cityTypeConfigMap.isEmpty()) {
            return builder;
        }
        SuiTangCityConfig cityConfig = config.getCityConfigMap().get(city.getCityId());
        SuiTangCityTypeConfig suiTangCityTypeConfig = cityTypeConfigMap.get(config.getCityTypeConfigKey(city.getWarType(), cityConfig.getType()));
        builder.setTeamNo(team.getTeamNo());
        builder.setArriveTime(team.getTeam() == null ? 0 : team.getTeam().getTime());
        if (team.getTeam() == null) {
            builder.setSoldierNum(team.getSoldierNum());
            builder.setSoldierMaxNum(team.getSoldierType() == 1 ? suiTangCityTypeConfig.getSoldierNum(calcRound()) : suiTangCityTypeConfig.getGeneralSoldierNum(calcRound()));
        } else {
            builder.setUser(parseSuiTangUserMsg(team.getTeamNo()));
            builder.setSoldierNum(getUserData(team.getTeamNo()).getTeam().getSoldierNum());
            builder.setSoldierMaxNum(getUserData(team.getTeamNo()).getTeam().getMaxSoldier());
        }
        builder.setSoldierType(team.getSoldierType());
        if (team.getTeam() != null) {
            // 玩家才有连胜
            builder.setWinStreak(getUserData(team.getTeamNo()).getTeam().getWinTimes());
        }
        return builder;
    }

    public SuiTang.SuiTangBattlefieldTeamMsg.Builder parseSuiTangBattlingTeamMsg(CrossSuiTangBattlefieldTeam team, int winTimes,
                                                                                 CrossSuiTangCity city) {
        SuiTang.SuiTangBattlefieldTeamMsg.Builder builder = SuiTang.SuiTangBattlefieldTeamMsg.newBuilder();
        Map<Integer, SuiTangCityTypeConfig> cityTypeConfigMap = config.getCityTypeConfigMap();
        if (cityTypeConfigMap == null || cityTypeConfigMap.isEmpty()) {
            return builder;
        }
        SuiTangCityConfig cityConfig = config.getCityConfigMap().get(city.getCityId());
        SuiTangCityTypeConfig suiTangCityTypeConfig = cityTypeConfigMap.get(config.getCityTypeConfigKey(city.getWarType(), cityConfig.getType()));
        builder.setTeamNo(team.getTeamNo());
        builder.setArriveTime(team.getTeam() == null ? 0 : team.getTeam().getTime());
        if (team.getTeam() == null) {
            builder.setSoldierNum(team.getSoldierNum());
            builder.setSoldierMaxNum(team.getSoldierType() == 1 ? suiTangCityTypeConfig.getSoldierNum(calcRound()) : suiTangCityTypeConfig.getGeneralSoldierNum(calcRound()));
        } else {
            builder.setUser(parseSuiTangUserMsg(team.getTeamNo()));
            builder.setSoldierNum(getUserData(team.getTeamNo()).getTeam().getSoldierNum());
            builder.setSoldierMaxNum(getUserData(team.getTeamNo()).getTeam().getMaxSoldier());
        }
        builder.setSoldierType(team.getSoldierType());
        if (team.getTeam() != null) {
            // 玩家才有连胜
            builder.setWinStreak(winTimes);
        }
        return builder;
    }

    public SuiTang.SuiTangBattlefieldFightTeamMsg.Builder parseSuiTangBattleFightTeamMsg(CrossSuiTangBattleResult ret,
                                                                                         CrossSuiTangCity city) {
        SuiTang.SuiTangBattlefieldFightTeamMsg.Builder builder = SuiTang.SuiTangBattlefieldFightTeamMsg.newBuilder();
        builder.setAtk(parseSuiTangBattlingTeamMsg(ret.getAtk(), ret.getWinType() == 1 ? 0 : ret.getWinTimes(), city));
        builder.setDef(parseSuiTangBattlingTeamMsg(ret.getDef(), ret.getWinType() == 1 ? ret.getWinTimes() : 0, city));
        builder.setFightStartTime(ret.getBattleStartTime());
        builder.setFightEndTime(ret.getBattleEndTime());
        builder.setBattle(parseSuiTangBattleResultMsg(ret));
        return builder;
    }

    public SuiTang.SuiTangBattleResultMsg.Builder parseSuiTangBattleResultMsg(CrossSuiTangBattleResult ret) {
        SuiTang.SuiTangBattleResultMsg.Builder builder = SuiTang.SuiTangBattleResultMsg.newBuilder();
        builder.setDefWin(ret.getWinType() == 1);
        builder.setDefHpReduce(ret.getDefHpReduce());
        builder.setAtkHpReduce(ret.getAtkHpReduce());
        return builder;
    }

    public SuiTang.SuiTangTeamMsg.Builder parseSuiTangTeamMsg(CrossSuiTangTeam team) {
        SuiTang.SuiTangTeamMsg.Builder builder = SuiTang.SuiTangTeamMsg.newBuilder();
        builder.setTeamStatus(mapActivityMgr.getTeamStatus(team).getValue());
        if (team.getFromCityId() != team.getCityId() && team.getArriveTime() > System.currentTimeMillis()) {
            builder.setCityId(team.getFromCityId());
            builder.setToCityId(team.getCityId());
        } else {
            builder.setCityId(team.getCityId());
            builder.setToCityId(0);
        }
        builder.setStartTime(team.getBeginMoveTime());
        builder.setArriveTime(team.getArriveTime());
        builder.setMaxSoldier(team.getMaxSoldier());
        builder.setSoldierNum(team.getSoldierNum());
        builder.setTargetCityId(team.getTargetCityId());
        builder.setIsAutoMove(team.isAutoMove());
        builder.setIsAutoBattle(team.isAutoBattle());
        builder.setAccCount(team.getSpeedUpNum());
        builder.setUser(parseSuiTangUserMsg(team.getUserId()));
        int buffId = 0;
        if (getUserData(team.getUserId()) != null) {
            buffId = config.getParamConfig().getHonoraryTitleBuffId(getUserData(team.getUserId()).getUserBaseInfo().getHonoraryTitle());
        }
        builder.setIsQianSan(buffId >= config.getParamConfig().getSuiTangJinJiaMinBuffId());
        builder.setCurBattleNum(team.getCurBattleNum());
        return builder;
    }

    public SuiTang.SuiTangUserMsg.Builder parseSuiTangUserMsg(long userId) {
        CrossSuiTangUserData userData = getUserData(userId);
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
        String nickname = userBaseInfo == null ? "" : userBaseInfo.getNickName();

        SuiTang.SuiTangUserMsg.Builder builder = SuiTang.SuiTangUserMsg.newBuilder();
        builder.setNickname(nickname);
        builder.setUserId(userId);
        builder.setDecoration(userBaseInfo == null ? "" : userBaseInfo.getDecoration());
        builder.setUnionId(userData.getUnionUid());
        return builder;
    }

    public SuiTang.SuiTangCityMsg.Builder parseSuiTangCityMsg(CrossSuiTangCity city) {
        SuiTang.SuiTangCityMsg.Builder builder = SuiTang.SuiTangCityMsg.newBuilder();
        builder.setCityId(city.getCityId());
        builder.setUnionId(city.getUnionId());
        builder.setStatus(city.getStatus());
        builder.setChangeStatusTime(city.getChangeStatusTime());
        builder.setHp(city.getNpcGuardList().size());
        builder.setMaxHp(city.getMaxHp());
        builder.setNeedDefensePeople(city.getNeedDefensePeople());
        builder.setUpdateDefensePeopleTime(city.getUpdateDefensePeopleTime());
        if (city.getStatus() == 0 && city.getMaxHp() > builder.getHp()) {
            builder.setIsFirst(city.getTeamRecoveryBeginTime() == 0);
            long recoverTime = builder.getIsFirst() ? config.getParamConfig().getSuiTangCitySoldierRecoverTimeFirst() : config.getParamConfig().getSuiTangCitySoldierRecoverTime();
            builder.setRecoverTime(city.getLastRecoveryExtraTeamTime() + recoverTime * DateHelper.SECOND_MILLIONS);
        }
        List<CrossSuiTangBattlefieldTeam> list = new ArrayList<>();
        for (CrossSuiTangBattlefieldTeam battlefieldTeam : city.getBattlefield().getDefTeamMap().values()) {
            if (battlefieldTeam.getTeam() != null) {
                list.add(battlefieldTeam);
            }
        }
        if (!list.isEmpty()) {
            // TODO：兵力排序
            list.sort((o1, o2) -> {
                Long soldierNum1 = o1.getSoldierNum();
                Long soldierNum2 = o2.getSoldierNum();
                return soldierNum2.compareTo(soldierNum1);
            });
        }
        for (int i = 0; i < 3 && i < list.size(); i++) {
            builder.addDefender(parseSuiTangUserMsg(list.get(i).getTeamNo()));
        }
        return builder;
    }

    public SuiTang.SuiTangCityEventMsg.Builder parseSuiTangCityEventMsg(CrossSuiTangCityEvent cityEvent) {
        SuiTang.SuiTangCityEventMsg.Builder builder = SuiTang.SuiTangCityEventMsg.newBuilder();
        builder.setCityId(cityEvent.getCityId());
        builder.setUnionId(cityEvent.getUnionId());
        builder.setRefreshTime(cityEvent.getRefreshTime());
        builder.setBuffId(cityEvent.getBuffId());
        builder.setEndTime(cityEvent.getEndTime());
        return builder;
    }

    public SuiTang.SuiTangUnionTempMsg.Builder parseSuiTangUnionTempMsg(CrossSuiTangUnionJoinData unionJoinData) {
        SuiTang.SuiTangUnionTempMsg.Builder builder = SuiTang.SuiTangUnionTempMsg.newBuilder();
        builder.setUnion(parseUnionBaseTempMsg(unionJoinData));
        builder.setUnionId(unionJoinData.getUnionUid());
        return builder;
    }

    public UnionProto.UnionBaseTempMsg.Builder parseUnionBaseTempMsg(CrossSuiTangUnionJoinData unionJoinData) {
        UnionBaseInfo unionBaseInfo = unionJoinData.getUnionBaseInfo();
        if (null == unionBaseInfo) {
            return null;
        }
        long masterId = unionJoinData.getMasterId();
        UserBaseInfo masterBaseInfo = CrossUserMgr.getUserBaseInfo(masterId);
        UnionProto.UnionBaseTempMsg.Builder msg = UnionProto.UnionBaseTempMsg.newBuilder();
        msg.setUnionAliasId(unionBaseInfo.getUnionAliasId());
        msg.setUnionName(unionBaseInfo.getUnionName());
        msg.addAllUnionFlag(UnionHelper.getUnionFlag(unionBaseInfo));
        msg.setExperience(unionBaseInfo.getExperience());
        msg.setMemberCount(unionBaseInfo.getMemberCount());
        msg.setIsAllowRandomJoin(unionBaseInfo.isAllowRandomJoin());
        msg.setTotalEarnSpeed(unionBaseInfo.getTotalEarnSpeed().toString());
        msg.setMasterUserId(masterId);
        msg.setMasterNickName(masterBaseInfo == null ? unionBaseInfo.getMasterNickName() : masterBaseInfo.getNickName());
        msg.setMasterVipExp(unionBaseInfo.getMasterVipExp());
        msg.setMasterDecoration(masterBaseInfo == null ? unionBaseInfo.getMasterDecoration() : masterBaseInfo.getDecoration());
        msg.setServerId(unionBaseInfo.getServerId());
        msg.setHideMasterVipAndAddress(unionBaseInfo.getHideVipAndAddress());
        msg.setSex(unionBaseInfo.getSex());
        msg.setCross(unionBaseInfo.isCross());
        msg.setHonerPoint(unionBaseInfo.getHonors());
        return msg;
    }

    public SuiTang.SuiTangCommanderDataSyncMsg.Builder parseSuiTangCommanderDataSyncMsg(CrossSuiTangUnionData unionData) {
        SuiTang.SuiTangCommanderDataSyncMsg.Builder builder = SuiTang.SuiTangCommanderDataSyncMsg.newBuilder();
        if (unionData == null) {
            builder.setUnionOwnerUserData(PlayerProto.PlayerBaseTempMsg.newBuilder());
            builder.setCommanderData(parseSuiTangCommanderDataTemp(new CrossSuiTangCommanderData()));
            builder.setUnionOwnerUserId(0);
            return builder;
        }
        CrossSuiTangCommanderData commanders = unionData.getCommanders();
        if (commanders.getUserId().isEmpty()) {
            builder.setUnionOwnerUserData(PlayerProto.PlayerBaseTempMsg.newBuilder());
            builder.setCommanderData(parseSuiTangCommanderDataTemp(new CrossSuiTangCommanderData()));
            builder.setUnionOwnerUserId(0);
            return builder;
        }
        builder.setUnionOwnerUserId(commanders.getUserId().get(0));
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(commanders.getUserId().get(0)); // 第一个是会长
        if (userBaseInfo != null) {
            builder.setUnionOwnerUserData(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        } else {
            builder.setUnionOwnerUserData(PlayerProto.PlayerBaseTempMsg.newBuilder());
        }
        builder.setCommanderData(parseSuiTangCommanderDataTemp(commanders));
        return builder;
    }

    public SuiTang.SuiTangCommanderDataTemp.Builder parseSuiTangCommanderDataTemp(CrossSuiTangCommanderData commanderData) {
        SuiTang.SuiTangCommanderDataTemp.Builder builder = SuiTang.SuiTangCommanderDataTemp.newBuilder();
        builder.setNotice(commanderData.getNotice());
        builder.setMajorCityId(commanderData.getMajorCityId());
        builder.setMinorCityId(commanderData.getMinorCityId());
        if (commanderData.getUserId().size() >= 2) {
            builder.setUserId(commanderData.getUserId().get(1));
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(commanderData.getUserId().get(1)); // 第二个是会长设置的指挥官
            if (userBaseInfo != null) {
                builder.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
            }
        }
        return builder;
    }

    public SuiTang.SuiTangUserRoundSyncMsg.Builder parseSuiTangUserRoundSyncMsg(CrossSuiTangUserRound userRound) {
        SuiTang.SuiTangUserRoundSyncMsg.Builder builder = SuiTang.SuiTangUserRoundSyncMsg.newBuilder();
        if (userRound == null) {
            return builder;
        }
        builder.setRound(userRound.getRound());
        builder.setActGroupId(userRound.getActGroupId());
        builder.setWarType(userRound.getWarType().getType());
        builder.setHomeCityId(userRound.getCityId());

        if (userRound.getRound() > 1) {
            CrossSuiTangUnionRound unionRoundData = unionActivityMgr.getUnionRoundData(getUserData(userRound.getUserId()).getUnionUid(), userRound.getRound() - 1);
            if (unionRoundData != null) {
                builder.setOldRank(unionRoundData.getRank());
                builder.setOldWarType(unionRoundData.getWarType().getType());
            }
        }

        if (crossSuiTangData.getActGroupMap().isEmpty()) {
            return builder;
        }
        Map<eSuiTangWarType, Map<Integer, CrossSuiTangGroup>> warTypeEnumMap = crossSuiTangData.getActGroupMap().get(calcRound());
        if (warTypeEnumMap.isEmpty()) {
            return builder;
        }
        for (Map<Integer, CrossSuiTangGroup> groupMap : warTypeEnumMap.values()) {
            for (CrossSuiTangGroup group : groupMap.values()) {
                for (String unionId : group.getUnionMap().keySet()) {
                    CrossSuiTangUnionRound unionRoundData = unionActivityMgr.getUnionRoundData(unionId);
                    if (unionRoundData != null) {
                        builder.addUnionList(parseSuiTangUnionMsg(unionRoundData));
                    }
                }
            }
        }

        SuiTang.SuiTangUnionGroupInfo.Builder builderYiJun = parseSuiTangUnionGroupInfo(eSuiTangWarType.WAR_TYPE_YIJUN);
        if (builderYiJun != null) {
            builder.addGroupList(builderYiJun);
        }
        SuiTang.SuiTangUnionGroupInfo.Builder builderXiaoQi = parseSuiTangUnionGroupInfo(eSuiTangWarType.WAR_TYPE_XIAOQI);
        if (builderXiaoQi != null) {
            builder.addGroupList(builderXiaoQi);
        }
        SuiTang.SuiTangUnionGroupInfo.Builder builderJinJun = parseSuiTangUnionGroupInfo(eSuiTangWarType.WAR_TYPE_JINJUN);
        if (builderJinJun != null) {
            builder.addGroupList(builderJinJun);
        }
        return builder;
    }

    public SuiTang.SuiTangUnionGroupInfo.Builder parseSuiTangUnionGroupInfo(eSuiTangWarType typeEnum) {
        SuiTang.SuiTangUnionGroupInfo.Builder builder = SuiTang.SuiTangUnionGroupInfo.newBuilder();
        Map<eSuiTangWarType, Map<Integer, CrossSuiTangGroup>> warTypeEnumMap = crossSuiTangData.getActGroupMap().get(calcRound());
        if (warTypeEnumMap.isEmpty()) {
            return null;
        }
        Map<Integer, CrossSuiTangGroup> groupMap = warTypeEnumMap.get(typeEnum);
        if (groupMap == null || groupMap.isEmpty()) {
            return null;
        }
        builder.setWarType(typeEnum.getType());
        builder.setGroupNum(groupMap.size());
        int unionNum = 0;
        for (CrossSuiTangGroup value : groupMap.values()) {
            unionNum += value.getUnionMap().size();
        }
        builder.setUnionNum(unionNum);
        return builder;
    }

    public SuiTang.SuiTangUnionMsg.Builder parseSuiTangUnionMsg(CrossSuiTangUnionRound unionRound) {
        SuiTang.SuiTangUnionMsg.Builder builder = SuiTang.SuiTangUnionMsg.newBuilder();
        builder.setUnionId(unionRound.getUnionUid());
        builder.setWarType(unionRound.getWarType().getType());
        builder.setActGroupId(unionRound.getActGroupId());
        builder.setRound(unionRound.getRound());
        builder.setHomeCityId(unionRound.getHomeId());
        builder.setCurrentCityScore(unionRound.getCurrentCityScore().intValue());
        CrossSuiTangUnionJoinData unionJoin = unionActivityMgr.getUnionJoin(unionRound.getUnionUid());
        // v6.9 改为赚钱
        builder.setTotalEarnSpeed(unionJoin.getUnionBaseInfo().getTotalPatronsAbility().toString());
        return builder;
    }

    public SuiTang.SuiTangBattlefieldRankMsg.Builder parseSuiTangBattlefieldRankMsg(CrossSuiTangBattlefieldRank rank) {
        SuiTang.SuiTangBattlefieldRankMsg.Builder builder = SuiTang.SuiTangBattlefieldRankMsg.newBuilder();
        builder.setUser(parseSuiTangUserMsg(rank.getUserId()));
        builder.setValue(rank.getZhanGong());
        builder.setKillNum(rank.getKillNum());
        return builder;
    }

    public SuiTang.SuiTangUnionBuGaoMsg.Builder parseSuiTangUnionBuGaoMsg(CrossSuiTangUnionBuGaoData buGaoData, boolean getReward) {
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(buGaoData.getUserId());
        if (userBaseInfo == null) {
            userBaseInfo = new UserBaseInfo();
        }

        SuiTang.SuiTangUnionBuGaoMsg.Builder tempMsg = SuiTang.SuiTangUnionBuGaoMsg.newBuilder();
        tempMsg.setUserId(buGaoData.getUserId());
        tempMsg.setNickName(userBaseInfo.getNickName());
        tempMsg.setType(buGaoData.getGoodId());
        tempMsg.setOrderNo("" + buGaoData.getBuGaoNo());
        tempMsg.setIsGet(getReward ? 1 : 0);
        return tempMsg;
    }

    public RandomHelper getRandomHelper() {
        return randomHelper;
    }

    public Map<eSuiTangWarType, Map<Integer, Map<Integer, Map<String, CrossSuiTangRankListModel>>>> getWarUserRankMap() {
        return warUserRankMap;
    }

    public void setWarUserRankMap(Map<eSuiTangWarType, Map<Integer, Map<Integer, Map<String, CrossSuiTangRankListModel>>>> warUserRankMap) {
        this.warUserRankMap = warUserRankMap;
    }

//    public CrossSuiTangRankListModel getUserRank() {
//        return userRank;
//    }

    public List<CrossSuiTangUserWarReportData> getNeedInsertUserReportList() {
        return needInsertUserReportList;
    }

    public List<CrossSuiTangCityWarReportData> getNeedInsertCityReportList() {
        return needInsertCityReportList;
    }

    public void saveCity() {
        Map<Integer, Map<eSuiTangWarType, Map<Integer, Map<Integer, CrossSuiTangCity>>>> cityMap = crossSuiTangData.getCityMap();

        cityMap.values().stream()
                .flatMap(warMap -> warMap.values().stream())
                .flatMap(groupMap -> groupMap.values().stream())
                .flatMap(cityMapTemp -> cityMapTemp.values().stream())
                .forEach(this::processSaveCity);
    }

    private void processSaveCity(CrossSuiTangCity city) {
        if (city.isInsertOption()) {
            SuiTangActivityBusiness.addCrossSuiTangCity(city);
        } else {
            SuiTangActivityBusiness.updateCrossSuiTangCity(city);
        }
    }

    public void saveCityEvent() {
        Map<Integer, Map<eSuiTangWarType, Map<Integer, Map<Integer, CrossSuiTangCityEvent>>>> cityMap = crossSuiTangData.getCityEventMap();

        cityMap.values().stream()
                .flatMap(warMap -> warMap.values().stream())
                .flatMap(groupMap -> groupMap.values().stream())
                .flatMap(cityMapTemp -> cityMapTemp.values().stream())
                .forEach(this::processSaveCityEvent);
    }

    private void processSaveCityEvent(CrossSuiTangCityEvent city) {
        if (city.isInsertOption()) {
            SuiTangActivityBusiness.addCrossSuiTangCityEvent(city);
        } else {
            SuiTangActivityBusiness.updateCrossSuiTangCityEvent(city);
        }
    }

    public void addUserWarReport(CrossSuiTangUserWarReportData reportData) {
        if (reportData == null) {
            return;
        }
        if (npcTestActivityMgr.isNpc(reportData.getUserIdDef()) || npcTestActivityMgr.isNpc(reportData.getUserIdAct())) {
            return;
        }
        synchronized (needInsertUserReportList) {
            needInsertUserReportList.add(reportData);
        }
    }

    public void addUserWarReportMemory(CrossSuiTangUserWarReportData reportData) {
        if (reportData == null) {
            return;
        }
        if (npcTestActivityMgr.isNpc(reportData.getUserIdDef()) || npcTestActivityMgr.isNpc(reportData.getUserIdAct())) {
            return;
        }
        synchronized (userWarReportDataMap) {
            List<CrossSuiTangUserWarReportData> reportDataList = userWarReportDataMap.getOrDefault(reportData.getUserIdAct(), new ArrayList<>());
            if (reportDataList.size() >= config.getParamConfig().getSuiTangPersonalBattleReportNumLimit()) {
                reportDataList.remove(0);
            }
            reportDataList.add(reportData);
            userWarReportDataMap.put(reportData.getUserIdAct(), reportDataList);

            List<CrossSuiTangUserWarReportData> reportDataListDef = userWarReportDataMap.getOrDefault(reportData.getUserIdDef(), new ArrayList<>());
            if (reportDataListDef.size() >= config.getParamConfig().getSuiTangPersonalBattleReportNumLimit()) {
                reportDataListDef.remove(0);
            }
            reportDataListDef.add(reportData);
            userWarReportDataMap.put(reportData.getUserIdDef(), reportDataListDef);
        }
    }

    public void addCityWarReport(CrossSuiTangCityWarReportData reportData) {
        if (reportData == null) {
            return;
        }
        synchronized (needInsertCityReportList) {
            needInsertCityReportList.add(reportData);
        }
    }

    public void addCityWarReportMemory(CrossSuiTangCityWarReportData reportData) {
        if (reportData == null) {
            return;
        }
        synchronized (cityWarReportMap) {
            List<String> unionIds = new ArrayList<>(reportData.getAtkCampId());
            if (!reportData.getDefCampId().isEmpty()) {
                unionIds.add(reportData.getDefCampId());
            }
            for (String unionId : unionIds) {
                List<CrossSuiTangCityWarReportData> cityWarReportDataList = cityWarReportMap.getOrDefault(unionId, new ArrayList<>());
                if (cityWarReportDataList.size() >= config.getParamConfig().getSuiTangCityBattleReportNumLimit()) {
                    cityWarReportDataList.remove(0);
                }
                cityWarReportDataList.add(reportData);
                cityWarReportMap.put(unionId, cityWarReportDataList);
            }

        }
    }

    public int getTaskNum() {
        return taskNum;
    }

    public int calcRound() {
        return crossSuiTangData.getBattleRound().intValue();
    }

    public boolean isBattleStep() {
        Long battleTime = config.getStage1TimeList().get(calcRound() - 1).get(1) - 10 * DateHelper.MINUTE_MILLIONS;
        if (System.currentTimeMillis() < battleTime) {
            return true;
        }
        return false;
    }

    public CrossSuiTangBarracksActivityMgr getBarracksActivityMgr() {
        return barracksActivityMgr;
    }

    public CrossSuiTangSyncActivityMgr getSyncActivityMgr() {
        return syncActivityMgr;
    }

    public CrossSuiTangRankActivityMgr getRankActivityMgr() {
        return rankActivityMgr;
    }

    public CrossSuiTangBattleActivityMgr getBattleActivityMgr() {
        return battleActivityMgr;
    }

    public CrossSuiTangLockMemberMgr getLockMemberMgr() {
        return lockMemberMgr;
    }

    public CrossSuiTangMapActivityMgr getMapActivityMgr() {
        return mapActivityMgr;
    }

    public CrossSuiTangUnionActivityMgr getUnionActivityMgr() {
        return unionActivityMgr;
    }

    public CrossSuiTangRoundActivityMgr getRoundActivityMgr() {
        return roundActivityMgr;
    }

    public CrossSuiTangNpcTestActivityMgr getNpcTestActivityMgr() {
        return npcTestActivityMgr;
    }

    public CrossSuiTangLogActivityMgr getLogActivityMgr() {
        return logActivityMgr;
    }
}
